[Rails] 投稿した住所をGoogle Map APIを使ってMapで表示する

# 目標

![ezgif.com-gif-maker (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974719/d72ad295-d7ba-444f-72eb-dcc687c33f46.gif)


今回はGoogle Map APIを使って住所投稿して投稿した住所をMapで表示する機能をつけます！


#　実装
実装する前にまずはGoogleMapAPIのキーを取得します。
取得の仕方は以下の記事がとても分かりやすいので参考にしてください！


https://qiita.com/nagaseToya/items/e49977efb686ed05eadb


## カラムの追加
APIキーが取得できたらまずは住所、緯度、経度を保存するためのカラムを追加します。

```ruby:ターミナル
$ rails g migration add_columns_to_events address:string latitude:float longitude:float
```
floatは少数点の値を扱うときに使う型です。

```ruby:ターミナル 
$ rails db:migrate
```
## カラムを保存できるようにする
追加したカラム`:addressを`保存できるようにしていきます。
まずはControllerでパラメータを許可していきます。

```ruby:events_controller.rb
 private

  def event_params
    params.require(:event).permit(:name, :text,:address #追加)
  end
```

続いてViewにformを追加します。

```ruby
<%= f.label :adress, '住所' %>
<%= f.text_field :address %>
```

## Geocoderを使って緯度、経度を取得する
経度、緯度の取得はgeocoderというgemを使います。

```ruby:Gemfile
gem 'geocoder'
```

```ruby:ターミナル 
$ bundle install
```

インストールできたらモデルに以下の記述をします

```ruby:model/event.rb
class Event < ApplicationRecord
    geocoded_by :address
    after_validation :geocode
end
```

`:address`の部分はmigrationファイルに記述した部分なので自分のに合わせてください。
この2行を`:address` `:latitude` `:longitude`のカラムのあるモデルに記述することで緯度、経度を取得することができます。

続いて詳しく住所を取得するために`geocoder`の設定をしていきます。

```ruby:ターミナル 
$ rails g geocoder:config
```
`geocoder`の設定ファイルが生成されるので記述していきます。
設定ファイルは全てコメントアウトされているので以下の部分のコメントアウトを外して入力してください。

```ruby:config/initializers/geocoder.rb
Geocoder.configure(
  # Geocoding options
  timeout: 5,                 # geocoding service timeout (secs)
  lookup: :google,         # name of geocoding service (symbol)
  api_key: 'API_KEY',               # API key for geocoding service
  units: :km,                 # :km for kilometers or :mi for miles
)
```

これで設定完了です！
あとはMapを表示するための記述をしていきましょう！

```
<div id='map'></div>

<style>
#map {
  height: 300px;
  width: 400px;
}
</style>

<script>
  let map
  
  function initMap(){
    geocoder = new google.maps.Geocoder()
    var test ={lat: <%= event.latitude %>, lng: <%= event.longitude %>};
  
    map = new google.maps.Map(document.getElementById('map'), {
      center: test,
      zoom: 15,
    });

    var contentString = '住所：<%= event.address %>';
    var infowindow = new google.maps.InfoWindow({
      content: contentString
    });
  
    marker = new google.maps.Marker({
      position:  test,
      map: map,
      title: contentString
    });
  }
</script>
<script src="https://maps.googleapis.com/maps/api/js?key='API_KEY'&callback=initMap" async defer></script>

```

`event.latitude` `event.longitude` `event.address`の部分は自分で設定した変数を渡してください。
Mapは`height`を設定しないと表示されないので`height`を必ず設定しましょう。

これで無事表示できました！

## カスタマイズ
最後にカスタマイズについてです。
Google Mapはデフォルトで十分なのですが今回表示したい部分が小さいので以下のようにカスタムボタン部分が重なって見づらくなっていました。
なので不要なボタンを消すカスタマイズをしました。

![スクリーンショット 2021-06-21 15.58.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974719/6d910dbd-d990-1397-cb51-5e81515deeb8.png)



```
<div id='map'></div>

<style>
#map {
  height: 300px;
  width: 400px;
}
</style>

<script>
  let map
  
  function initMap(){
    geocoder = new google.maps.Geocoder()
    var test ={lat: <%= event.latitude %>, lng: <%= event.longitude %>};
  
    map = new google.maps.Map(document.getElementById('map'), {
      center: test,
      zoom: 15,
　　　　　　　　　　　#--------- 追加 -----------
      mapTypeControl: false,  
      streetViewControl: false
     # -------------------------
    });

    var contentString = '住所：<%= event.address %>';
    var infowindow = new google.maps.InfoWindow({
      content: contentString
    });
  
    marker = new google.maps.Marker({
      position:  test,
      map: map,
      title: contentString
    });
  }
</script>
<script src="https://maps.googleapis.com/maps/api/js?key='API_KEY'&callback=initMap" async defer></script>

```
こうすることで不要なボタンを消すことができました。

![スクリーンショット 2021-06-21 15.59.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974719/7801e4c0-8aeb-0e40-7f2f-118de948c3a2.png)

Google Mapは他にも沢山カスタマイズ方法があるので以下のサイトを参考にしてみてください！
https://www.granfairs.com/blog/staff/google-maps-api-03

## APIキーの管理
APIキーをそのままGithubにpushしてしまうと悪用されるかもしれないのでGithubにpushしないように設定していきます。

gemをインストール

```ruby:Gemfile
gem "dotenv-rails"
```

```ruby:ターミナル 
$ bundle install
```

インストールできたら`.env`ファイルを作成します。

```ruby:ターミナル 
$ touch .env
```

この作成した`.env`ファイルにAPIキーを記述していきます。

```ruby:.env
MAP_API_KYE=YOUR_API_KYE 
```
入力したらこの`.env`ファイルを`gitignore`に入力します。

```ruby:gitignore
.env
```

`gitignore`に入力することで入力したファイルはGithubにpushされなくなります。


そして最後にAPIキーを入力していた部分を書き換えていきましょう。

```ruby:config/initializers/geocoder.rb
api_key: ENV['MAP_API_KEY'],        
```

```ruby
<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['MAP_API_KEY'] %>&callback=initMap" async defer></script>
```

これで完成です！


# おまけ
本番環境で地図が表示されなかった場合は以下の記事を参考にしてみてください！

https://qiita.com/aaaasahi_17/items/5845a3cf217041567738