Ruby on Rails で gmaps4rails と geocoder というライブラリを使って、ユーザーが入力したアドレスから、経度と緯度を取得して、Google Map を表示できるように実装していきたいと思います。
Google Maps for Rails
https://github.com/apneadiving/Google-Maps-for-Rails
Geocoder
https://github.com/alexreisner/geocoder
環境はこちらです
1 2 3 4 5 |
ruby 2.5.1 rails 5.1.6 docker 18.06.0-ce gmaps4rails 2.1.2 geocoder 1.5.0 |
準備
Gemfile
1 2 |
gem "gmaps4rails" gem "geocoder" |
1 |
$ bundle install |
あらかじめ Article モデルがあるとして、そこに緯度・経度のデータを格納するカラムを追加します。
1 2 |
$ rails g migration add_address_to_articles address:string latitude:float longitude:float $ rails db:migrate |
app/assets/javascripts/application.js
1 2 |
//= require underscore //= require gmaps/google |
こちらからunderscore-min.jsの中身を全てコピーして、underscore.jsという名前で作成し、 app/assets/javascripts/ に配置します。
Models
対象となるモデルに次の記述を追加すると、 geocoder が address から経度・緯度を取得してくれます。
app/models/article.rb
1 2 3 4 5 6 |
class Article < ApplicationRecord geocoded_by :address after_validation :geocode end |
Google APIキー
Google Maps JavaScript APIを使うためにはAPIキーが必要です。
下記URLにGoogleアカウントでログインしてAPIキーを取得してください。
https://console.developers.google.com/?hl=ja
対象レイアウトの head 内に以下の script を読み込ませます。Google Map の APIキーは環境変数に入れています。
app/views/layouts/application.html.erb
1 2 |
<script src="//maps.google.com/maps/api/js?key=<%= ENV['GMAP_API_KEY'] %>"></script> <script src="//cdn.rawgit.com/mahnunchik/markerclustererplus/master/dist/markerclusterer.min.js"></script> |
Views
オプションで scrollwheel を false に設定するとスクロールイベント(ページのスクロール中にMapが拡大・縮小する)を無効にできます。
handler.getMap().setZoom(拡大率); でマップの拡大率を調節してください。
app/views/articles/show.html.erb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<div id="map" style='width: 100%; height: 500px;'></div> <script type="text/javascript"> handler = Gmaps.build('Google'); handler.buildMap({ provider: { scrollwheel: false }, internal: {id: 'map'}}, function(){ markers = handler.addMarkers([ { "lat": <%= @article.latitude %>, "lng": <%= @article.longitude %>, "infowindow": '<p><%= @article.title %></p><p><%= @article.address %></p><p><%= link_to "Googleマップで見る" ,"https://maps.google.co.jp/maps?q=loc:#{@article.latitude},#{@article.longitude}&iwloc=J",target: "_blank" %></p>' } ]); handler.bounds.extendWith(markers); handler.fitMapToBounds(); handler.getMap().setZoom(17); }); </script> |
Controllers
ストロングパラメータも忘れずに設定します。
app/controllers/articles_controller.rb
1 2 3 4 5 |
def article_params params.require(:article).permit( :title, :address, :latitude, :longitude ) end |
ユーザーがアドレスを入力できるように、 field を追加します。
app/views/articles/_form.html.erb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<%= form_for @article do |f| %> <div class="field"> <%= f.label :title %> <%= f.text_field :title %> </div> <div class="field"> <%= f.label :address %> <%= f.text_field :address %> </div> <div class="actions"> <%= f.submit %> </div> <% end %> |
createすると longitude, latitude に経度・緯度の値が格納されて マップが表示されます。
1 |
SQL (8.3ms) INSERT INTO "articles" ("user_id", "title", "created_at", "updated_at", "address", "latitude", "longitude") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["user_id", 2], ["title", "東京です"], ["created_at", "2018-08-12 14:35:05.224933"], ["updated_at", "2018-08-12 14:35:05.224933"], ["address", "東京都千代田区"], ["latitude", 35.6938097], ["longitude", 139.7532163]] |
以上です!ご覧いただき、ありがとうございました!!😊