LoginSignup
8
6

More than 3 years have passed since last update.

【Rails6】Google Map をアプリに埋め込み、入力した住所にマーカーをつける。【細かいところの確認】

Last updated at Posted at 2020-10-21

簡単に実装できるはずのGoogleMapAPIですが数々の沼にハマったので細かく注意していきます。

環境

Rails 6.0.0
Ruby 2.6.5
EC2
Amazon Linux2
Nginx
mariaDB
Capistrano

機能

住所を入れると48b7ab460e405caaf463dd4963cd52af.png
DBに住所が保存、緯度経度が自動で算出されて
f57e6c8b1a108791d56e024334075861.png

表示されます。
d801305aebecc331b0cfd2a2bb7970d2.jpg

Google Mapをアプリに埋め込む

Google Map API(サービス紹介ページ)

Google Map APIは、GoogleCloudのサービスのひとつで、GoogleCloudPlatformというコンソールから操作します、まずはそこで、Google Map javascript APIのAPIKeyを取得します。

GoogleCloudPlatformへ

☆Googleのアカウントがなければまずこちらから登録してください。
Googleアカウント登録
アカウントを作成したら(持っていたら)コンソールへ
https://console.cloud.google.com/

プロジェクトを作成し、APIKeyを取得→地図表示

https://qiita.com/nagaseToya/items/e49977efb686ed05eadb
一連の流れはこちらにわかりやすく書かれています。

今回は、ここに加えて任意の住所記録、保存、出力します。

Geocording

緯度と経度を算出して、特定の位置を見つけてくれる機能です。gemのGeocoderと、Google CloudのGeocodeing APIというサービスを使います。
gemだけでも位置情報を取得することはできますが、「東京駅」では取得できても、「東京都〇〇区〇〇○○ー◯○」という具体的なアドレスでは取得できません。また取得できたりできなかったりします。そのためにより性能の良いGeocodeing APIも使えるようにします。

コード

モデルは作成されているとします。(例Performancesモデル)

①マイグレーションファイルを作成(カラム追加)

% rails g migration AddColumnsToPerformances

・入力された住所addressカラム
・geocodeによって自動で算出される緯度、経度カラム

class AddColumnsToPerformances < ActiveRecord::Migration[6.0]
  def change
    add_column :performances, :address, :string
    add_column :performances, :latitude, :float
    add_column :performances, :longitude, :float
  end
end
% rails db:migrate

rollbackでもカラムは変更できますが、データが消えるのでなるべくadd_column(カラム追加)にすると良いと思います!

②入力フォームの作成

保存先はaddressのみで大丈夫です。

<%= form_with(model: @performance, local: true) do |f| %>
***抜粋***
<label for="group-name">住所(GoogleMap表示)</label>
<span class="indispensable-any">任意</span>
<%= f.text_area :address,class:"new-performance-box", id:"gmap", placeholder:"Google Mapの住所をコピーして貼り付けてください" %>  
***抜粋***

③コントローラー

ストロングパラメーターでaddressを指定します。

performances_controller.erb
before_action :set_performance, only: [:表示させるview]

def create
   @performance = Performance.new(performance_params)
   if @performance.valid?
     @performance.save
     redirect_to "/users/#{current_user.id}"
   else
     render :new
   end
end

def 表示させるview
    @performance = Performance.new(performance_params)
end

private

def set_performance
   @performance = Performance.find(params[:id])
end

def performance_params
 params.require(:performance).permit(:address).merge(user_id: current_user.id)
end

④ビュー

CSSは別記してます。
zoomControl: false,
mapTypeControl: false,
fullscreenControl: false,
treetViewControl: false,
は拡大縮小ボタンなどを消す地図表示のオプションです。

<div id='map'>
<script>
let map
function initMap(){
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: <%= @performance.latitude %>, lng: <%= @performance.longitude %>},
    zoom: 15,
       zoomControl: false,
       mapTypeControl: false,
       fullscreenControl: false,
       streetViewControl: false,
  });

  marker = new google.maps.Marker({
    position: {lat: <%= @performance.latitude %>, lng: <%= @performance.longitude %>},
    map: map
  });
   geocoder = new google.maps.Geocoder()
}
</script>
  <script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GOOGLE_MAP_API'] %>&callback=initMap" async defer></script>
</div>

※key=<%= ENV['GOOGLE_MAP_API'] %>の表記は充分気をつけてください!ここで=の位置が違うだけで全てうまくいきません・・・

⑤モデル

これでgeocordが緯度経度を算出してカラムに保存してくれます

performance.rb
geocoded_by :address
after_validation :geocode, if: :address_changed?

※if: :address_changed?がないと作用しないことがあるので気をつけてください!私はこれを書かないとダメでした

⑥Geocording APIを使用するための記述

% rails generate geocoder:config
/config/initializes/geocoder.rb

Geocoder.configure(
  # Geocoding options
  # timeout: 5,                 # geocoding service timeout (secs)
  lookup: :google,         # name of geocoding service (symbol)
  # ip_lookup: :ipinfo_io,      # name of IP address geocoding service (symbol)
  # language: :en,              # ISO-639 language code
  use_https: true,           # use HTTPS for lookup requests? (if supported)
  # http_proxy: nil,            # HTTP proxy server (user:pass@host:port)
  # https_proxy: nil,           # HTTPS proxy server (user:pass@host:port)
  api_key: 'YOUR_API_KEY',               # API key for geocoding service
  # cache: nil,                 # cache object (must respond to #[], #[]=, and #del)
  # cache_prefix: 'geocoder:',  # prefix (string) to use for all cache keys

  # Exceptions that should not be rescued by default
  # (if you want to implement custom error handling);
  # supports SocketError and Timeout::Error
  # always_raise: [],

  # Calculation options
  units: :km # :km for kilometers or :mi for miles
  # distances: :linear          # :spherical or :linear
)

うまくいかない時の確認事項

・環境変数の設定
・viewの記述
・モデルのメソッド
・geocorder.rb

%rails c
[1] pry(main)> Geocoder.coordinates("〒150-0043 東京都渋谷区道玄坂2丁目1")
=> [35.6591376, 139.7007901]

で中身を変えながら出力されるか試してみる
・Google Map javascriptと、Geocoding APIのAPIkeyを一緒にしている場合、APIをもうひとつ作成し、別々にしてみる。
・本番環境での環境変数設定

[ec2-user@〜〜〜〜〜〜〜]$ sudo vim /etc/environment

変数設定後exit→再起動

[ec2-user@〜〜〜〜〜〜〜]$ env | grep YOUR_API_KEY

で確認
・EC2サーバーから再起動してみる(私はこれで最終的に本番環境で確認が取れました)

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6