目標
ユーザーが登録した住所をマップの中心に表示し、マーカーを立てる。
開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina
前提
下記実装済み。
・Slim導入
・ログイン機能実装
・Google Map表示
gem 'geocoder'
だけでは精度が低い(番地指定が出来ない地域がある)為、
Geocoding API
を使用して高精度で住所から緯度経度を特定出来る様に実装していきます。
Geocoding API
有効化
1.下記リンクにアクセス
2. 「APIの概要に移動」をクリック
3.「ライブラリ」をクリック
4.検索フォームに「geo」と入力し、「Geocoding API」をクリック
5.「有効にする」をクリック
6.赤枠で囲われている箇所をクリック
7.プルダウンメニューが表示されるので、「全てのGoogle Maps API」をクリック
8.「認証情報」をクリック
9.「APIキーの名前」をクリック
10.認証情報の設定をする
①APIの制限
キーを制限
を選択し、プルダウンメニューからGeocoding API
を選択する。
②Maps JavaScript API
と、Geocoding API
が選択されている事を確認して、保存
をクリック
11.APIが2個になっているかを確認
APIを追加した事でAPIキーが変更されるという事は無いので、これで完了。
実装
1.Gemを導入
gem 'gon'
gem 'geocoder'
gem 'gon'
➡︎ コントローラーで定義したインスタンス変数をビューのJavaScript内で使用出来る様にする。
gem 'geocoder'
➡︎ 住所から緯度経度を算出する。
$ bundle
2.geocorder
の設定ファイルを作成し、編集
$ touch config/initializers/geocoder.rb
# 追記
Geocoder.configure(
lookup: :google,
api_key: ENV['GOOGLE_MAP_API']
)
これでGeocoding API
を使用する事ができ、緯度経度の算出が高精度で行えます。
3.カラムを追加
$ rails g migration AddColumnsToUsers address:string latitude:float longitude:float
class AddColumnsToUsers < ActiveRecord::Migration[5.2]
def change
add_column :users, :address, :string
add_column :users, :latitude, :float
add_column :users, :longitude, :float
end
end
$ rails db:migrate
4.モデルを編集
# 追記
geocoded_by :address
after_validation :geocode
geocoded_by :address
➡︎ addressカラムを基準に緯度経度を算出する。
after_validation :geocode
➡︎ 住所変更時に緯度経度も変更する。
5.コントローラーを編集
①application_controller.rb
を編集
ストロングパラメーターに「address」を追加します。
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :name, :address])
end
②users_controller.rb
を編集
def show
@user = User.find(params[:id])
gon.user = @user # 追記
end
6.ビューを編集
①application.html.slim
を編集
gon
を読み込みます。
CSSとJavaScriptより先に読み込んでいる事に注意して下さい。
doctype html
html
head
title
| Bookers2
= csrf_meta_tags
= csp_meta_tag
= include_gon # 追記
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
②新規会員登録画面に住所入力フォームを追加
= f.label :address, '住所'
br
= f.text_field :address, class: 'form-control'
br
③マップを編集
#map style='height: 500px; width: 500px;'
- google_api = "https://maps.googleapis.com/maps/api/js?key=#{ ENV['GOOGLE_MAP_API'] }&callback=initMap".html_safe
script{ async src=google_api }
javascript:
let map;
function initMap() {
geocoder = new google.maps.Geocoder()
map = new google.maps.Map(document.getElementById('map'), {
// コントローラーで定義した変数から緯度経度を呼び出し、マップの中心に表示
center: {
lat: gon.user.latitude,
lng: gon.user.longitude
},
zoom: 12,
});
marker = new google.maps.Marker({
// コントローラーで定義した変数から緯度経度を呼び出し、マーカーを立てる
position: {
lat: gon.user.latitude,
lng: gon.user.longitude
},
map: map
});
}
注意
turbolinks
を無効化しないと地図が切り替わらないので、必ず無効化しておきましょう。