学生向けプログラミング入門 | 無料

学生向けにプログラミングを無料で解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails, Python, Django

Rails6.1 | 民泊予約アプリ作成 | 22 | Autocompleteとgeocoderの利用

↓↓クリックして頂けると励みになります。


21 | Amazon S3】 << 【ホーム】 >> 【23 | Application Helper



Rails 6.1を使用してGoogleの自動補完(Autocomplete)を実装するには、以下のステップに従うことができます。
Googleの自動補完は、通常、Google Places APIを使用して実装されます。


まずはGoogle Cloud PlatformにGoogleアカウントでログインしてAPIキーを取得してください。
手順は以下の通りにお願いします。
mrradiology.hatenablog.jp


GemFileに以下のgemを追加します。

gem 'geocoder', '~> 1.8', '>= 1.8.2'


ターミナルでbundle installを実行してGemをインストールします。
コマンド
bundle


住所が保存されると自動的に経度と緯度が取得され、データベースに保存されるようになります。
経度と緯度は latitude および longitude という名前のカラムに自動的に格納されます。
このルールに則り、部屋モデルに経度と緯度のカラムを追加します。


コマンド
rails g migration AddFieldsToRoom latitude:float longitude:float


マイグレーションを適用します。
コマンド
rails db:migrate


モデル(app/models/room.rb)に以下の記述を追加します。

  geocoded_by :address
  after_validation :geocode, if: :address_changed?



【app/models/room.rb】7行目

class Room < ApplicationRecord
  
  belongs_to :user

  has_many_attached :photos
  
  geocoded_by :address
  after_validation :geocode, if: :address_changed?

  validates :home_type, presence: true
  validates :room_type, presence: true
  validates :accommodate, presence: true
  validates :bed_room, presence: true
  validates :bath_room, presence: true

end



「config\initializers」フォルダに「geocoder.rb」ファイルを新規作成します。


新規作成 「config/initializers/geocoder.rb」

Geocoder.configure(
  api_key: 'ご自分のAPIキーを入れて下さい',
  use_https: true,
  timeout: 5
)



ビューを作成します。
「app/views/rooms/location.html.erb」ファイルを以下のように編集します。
APIキーはご自分のものを入れてください。
addressを入力するフィールドに「id: "autocomplete"」を追加し、スクリプトでリンクさせています。


記述編集 【app/views/rooms/location.html.erb】

<script src="https://maps.googleapis.com/maps/api/js?key=ご自分のAPIキーを入力してください&libraries=places&callback=initAutocomplete" async defer>
</script>

<div class="container mt-4">
    <div class="row">
        <div class="col-md-3">
            <%= render 'room_menu' %>
        </div>
        <div class="col-md-9">

            <div class="card">
                <div class="card-body">
                <h4 class="mt-4 mb-4"><b>部屋の住所</b></h4>
                    <%= form_for @room do |f| %>
                        <div class="mb-4">
                            <%= f.label :住所 %>
                            <%= f.text_field :address, placeholder: "住所を入力", class: "form-control w-100", required: true, id: "autocomplete" %>
                        </div>
                        <div>
                            <%= f.submit "保存", class: "btn btn-danger w-100" %>
                        </div>
                    <% end %>
      
                </div>

            </div>

        </div>

    </div>
</div>

<script>
let autocomplete;

function initAutocomplete() {
    autocomplete = new google.maps.places.Autocomplete(
        document.getElementById('autocomplete'),
        {
            types: ["establishment"],
            componentRestrictions: { country: ['JP'] },
            fields: ["place_id", "geometry", "name"],


        });
    
}

</script>



コントローラーに経度、緯度カラムのパーミッションを追加します。
「app/controllers/rooms_controller.rb」ファイルの79行目の記述を変更します。

params.require(:room).permit(:home_type, :room_type, :accommodate, :bed_room, :bath_room, :listing_name, :summary, :address, :latitude, :longitude, :is_tv, :is_kitchen, :is_air, :is_heating, :is_internet, :price, :active, :description)



記述追加 【app/controllers/rooms_controller.rb】

class RoomsController < ApplicationController

  protect_from_forgery except: [:upload_photo]

  before_action :set_room, except: [:index, :new, :create]
  before_action :authenticate_user!, except: [:show]
  before_action :is_authorised, only: [:listing, :pricing, :description, :photo_upload, :delete_photo, :amenities, :location, :update]

  def index
     @rooms = current_user.rooms
  end

  def new
    @room = current_user.rooms.build
  end

  def create
    @room = current_user.rooms.build(room_params)
    if @room.save
      redirect_to listing_room_path(@room), notice: "保存しました。"
    else
      flash[:alert] = "問題が発生しました。"
      render :new
    end
  end

  def show
  end

  def listing
  end

  def pricing
  end

  def description
  end

  def photo_upload
  end

  def amenities
  end

  def location
  end

  def update

    new_params = room_params
    new_params = room_params.merge(active: true) if is_ready_room

    if @room.update(new_params)
      flash[:notice] = "保存しました。"
    else
      flash[:alert] = "問題が発生しました。"
    end
    redirect_back(fallback_location: request.referer)
  end

  def upload_photo
    @room.photos.attach(params[:file])
    render json: { success: true }
  end

  def delete_photo
    @image = ActiveStorage::Attachment.find(params[:photo_id])
    @image.purge
    redirect_to photo_upload_room_path(@room)
  end


  private
  def set_room
    @room = Room.find(params[:id])
  end

  def room_params
    params.require(:room).permit(:home_type, :room_type, :accommodate, :bed_room, :bath_room, :listing_name, :summary, :address, :latitude, :longitude, :is_tv, :is_kitchen, :is_air, :is_heating, :is_internet, :price, :active, :description)
  end

  def is_authorised
    redirect_to root_path, alert: "権限がありません。" unless current_user.id == @room.user_id
  end
  
  def is_ready_room
    !@room.active && !@room.price.blank? && !@room.listing_name.blank? && !@room.photos.blank? && !@room.address.blank?
  end

end



これで住所の予測変換ができるようになりました。
ブラウザを確認します。
http://localhost:3000/rooms/1/location

住所予測変換
住所予測変換



住所が保存されると自動的に経度と緯度が取得され、データベースに保存されます。
経度と緯度は latitude および longitude カラムに格納されますが、詳細住所はなかなか難しいです。
保存して動作を確認してください。


21 | Amazon S3】 << 【ホーム】 >> 【23 | Application Helper


↓↓クリックして頂けると励みになります。