27
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RUNTEQ Advent Calendar 2023Advent Calendar 2023

Day 15

【Rails7】Maps JavaScript APIを使って投稿を地図上にピンで表示する

Last updated at Posted at 2023-12-14

自己紹介

はじめまして、はると申します。現在はスクールに通いながら学習をしています。
今回、スクール内のアドベントカレンダーに参加し、『初めて学んだ技術』 というテーマで記事を書きました🐥

概要

Google MapのAPIを利用し、地図上に投稿の一覧をピンで表示させます。
(新規投稿を作成する機能の実装は含みません)

  • Maps JavaScript API
  • Geocoding API

環境

  • Ruby: 3.2.2
  • Rails: 7.0.8
  • esbuild

初学者のため、間違っている箇所や、紹介した方法よりも良い方法があるかもしれませんので、その際は教えて頂けると嬉しいです🙇

APIキーの準備

初めてGoogle Cloud Platformを使う想定で記載します。すでに登録済みの方は使用するAPIの有効化に進んでください。

Google Cloud Platformにログイン

Google Cloud Platformにアクセスし、無料で利用開始から案内に沿って初期設定を行います。
Map javaScript APIは無料トライアルで使えるAPIには含まれていないため、この時に、クレジットカード情報も登録しておくと良いです。

Image from Gyazo

お支払い方法の設定

ログインができたら、Google Cloudのコンソールに遷移されます。
無料トライアルの状態であることがページ上部に表示されているかと思います。
有効化のボタンから、課金の有効化をします。
(課金にしても、無料トライアルの残りクレジットを使い切るまで or 3ヶ月間は、課金が開始されません)

これをしないと、APIキーが使えないエラーが後で起こるので、設定しておきましょう。

使用するAPIの有効化

コンソール画面左上のメニューを開き、APIとサービス内の、ライブラリに進みます。
Image from Gyazo

このような画面に遷移するので、検索フォームから、Maps JavaScript APIと、Geocoding APIを検索します。
Image from Gyazo

2つのAPIを有効化します。
Image from Gyazo
Image from Gyazo

有効化した際に表示されるAPIキーを控えておきます。(後でいつでも確認できます)

APIの制限をつける(任意)

念の為、セキュリティ上、不正利用された際などに必要以上にAPIを使用されないよう、
選択したAPIしか使えなくなる制限をかけておきます。

APIとサービスにアクセスした状態で、サイドバーから認証情報にアクセスします。
Image from Gyazo

先ほど発行されたAPIキーが表示されているため、クリックして詳細ページへ移動します。
Image from Gyazo

APIの制限で、キーを制限を選択し、Maps JavaScript APIGeocoding APIにチェックを入れて設定を保存します。
Image from Gyazo
Image from Gyazo

APIの導入

rails newしてから初めてAPIを導入する想定で記載します。すでに.env等の設定が終わっている方はAPIキーの設定・表示確認に進んでください。

APIキーを扱うための準備(重要⭕️)

  1. Gemfileに下記を追加し、$ bundle installを実行します。

    Gemfile
    gem 'dotenv-rails'
    

     

  2. .gitignoreファイルに下記を追加

    .gitignore
    /.env
    

    この作業を忘れると、GitHubにAPIキー(機密情報)を載せてしまう可能性があるので、先に済ませておきましょう!

  3. $ touch .envで.envファイルを作成します。
     

APIキーの設定・表示確認

  1. .envファイル内に取得したAPIキーを記載します。
    .env
    GOOGLE_MAPS_API_KEY = "取得したAPIキーをここに記載"
    
     
  2. 表示確認のため、試しにどこかのビューに下記を記載してみます。(任意)
    hoge.html.erb
    <!-- マップを表示する要素 -->
    <div id="map" style="height: 600px;"></div>
    
    <script>
      // 地図を初期化する関数
      function initMap() {
        // 地図のオプション
        const mapOptions = {
          center: { lat: 35.6803997, lng: 139.7690174 }, // 地図の初期表示位置(東京)
          zoom: 10 // ズームレベル
        };
    
        // 地図を指定した要素に表示
        const map = new google.maps.Map(document.getElementById('map'), mapOptions);
      }
    </script>
    <script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV["GOOGLE_MAPS_API_KEY"] %>&callback=initMap"></script>
    
     
  3. 地図が表示されていればAPIの導入は成功です🎉(任意)
    Image from Gyazo 

投稿に関する機能作成

  1. Postモデル、postsテーブルを作成します。
    $ rails g model Post title:string addless:text latitude:float longitude:floatを実行します。
    投稿の中に文章など含めたいものがあれば、一緒にカラムを追加して構いません。今回は記事のため最低限、titleのみを入れています。
     

  2. 生成されたマイグレーションファイルを編集します。

    xxxxxxxxxxxxxx_create_posts.rb
    class CreatePosts < ActiveRecord::Migration[7.0]
      def change
        create_table :posts do |t|
          t.string :title, null: false
          t.text :address, null: false
          t.float :latitude, null: false
          t.float :longitude, null: false
    
          t.timestamps
        end
      end
    end
    

     

  3. $ rails db:migrateを実行します。
     

  4. コントローラー、indexアクションを作成します。
    $ rails g controller Postsを実行します。

    posts_controller.rb
    class PostsController < ApplicationController
      def index
        @posts = Post.all
      end
    end
    

     

  5. ルーティングに下記を追加します。

    routes.rb
    resources :posts, only: %i[index]
    

     

  6. Gemfileに下記を追加し、$ bundle installを実行します。

    Gemfile
    gem "geocoder"
    

     

  7. $ rails g geocoder:configを実行します。
     

  8. config/initializers/geocoder.rbが生成されるので、以下のように編集します。

    geocoder.rb
    Geocoder.configure(
      # Geocoding options
      # timeout: 3,                 # 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: ENV['GOOGLE_MAPS_API_KEY'],               # API key for geocoding service
      # cache: nil,                 # cache object (must respond to #[], #[]=, and #del)
    
      # 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: :mi,                 # :km for kilometers or :mi for miles
      # distances: :linear          # :spherical or :linear
    
      # Cache configuration
      # cache_options: {
      #   expiration: 2.days,
      #   prefix: 'geocoder:'
      # }
    )
    

     

  9. Postモデルのファイルを編集します。

    post.rb
    class Post < ApplicationRecord
      geocoded_by :address
      after_validation :geocode
    end
    

     

  10. views/posts/index.html.erbを作成します。

    index.html.erb
    <div id="map" style="height: 600px;"></div>
    
    <script>
      function initMap() {
        // 地図要素を取得する(マーカーを表示させるために必要)
        const mapElement = document.getElementById('map');
    
        const mapOptions = {
          center: { lat: 35.6803997, lng: 139.7690174 },
          zoom: 10
        };
    
        const map = new google.maps.Map(mapElement, mapOptions);
    
        // マーカーを追加(Postの情報からマーカーを追加する)
        <% @posts.each do |post| %>
          new google.maps.Marker({
            position: {lat: <%= post.latitude %>, lng: <%= post.longitude %>}, 
            map: map,
            title: '<%= j post.title %>'
          });
        <% end %>
      }
    </script>
    <script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV["GOOGLE_MAPS_API_KEY"] %>&callback=initMap"></script>
    

マップ上に投稿がピンで表示されているか動作確認

今回は新規投稿を作成する機能までは実装しないため、
seedデータを使って、地図上に投稿が表示されるかの動作確認をします。

  1. Gemfileに下記を追加し、$ bundle installを実行します。

    Gemfile
    gem 'faker'
    

     

  2. db/seeds.rbを編集します。
    Fakerは架空の住所を生成するためのツールのため、実在する緯度・経度にならない可能性があるので、addressではなく緯度と経度に直接Fakerを使用しています。

    seeds.rb
    10.times do |n|
      latitude = Faker::Address.latitude.to_f
      longitude = Faker::Address.longitude.to_f
      Post.create!(
        title: "Example Title #{n + 1}",
        address: "Example Address #{n + 1}",
        latitude: latitude,
        longitude: longitude,
      )
    end
    

     

  3. $ rails db:seedを実行します。
     

  4. /postsにアクセスして、地図上にpostsテーブルに登録されている位置情報のピンが表示されていれば、成功です!🥳🎊

    Fakerで作ったpostの位置情報は、世界の中からランダムに作られるため、ズームレベルを遠くしてみると、ピンが表示されていることを確認できます。
    Image from Gyazo

まとめ

投稿データをMap上にピンで表示する方法をまとめました。
アプリ開発を始めたばかりで、APIを触るのも、Map JavaScript APIも初めてでしたが、表示することができて良かったです。
この後は、ユーザーが投稿したデータを表示できるようにするために、投稿の作成機能も実装していきたいと思います✊🏻
$\tiny{そちらもこの記事の続きとして、いつか記事にしたいと思います}$


追記:続き書きました!✏️

参考記事

27
17
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
27
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?