Google Cloud PlatformにGoogleアカウントでログインしてAPIキーを取得してください。
手順は以下の通りにお願いします。
mrradiology.hatenablog.jp
記述追加 GemFile(69行目)
#googleマップ gem 'geocoder', '~> 1.4'
GemFile
source 'https://rubygems.org' git_source(:github) do |repo_name| repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") "https://github.com/#{repo_name}.git" end # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.0.7', '>= 5.0.7.1' # Use postgresql as the database for Active Record gem 'pg', '>= 0.18', '< 2.0' # Use Puma as the app server gem 'puma', '~> 3.0' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' # Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.2' # See https://github.com/rails/execjs#readme for more supported runtimes # gem 'therubyracer', platforms: :ruby # Use jquery as the JavaScript library gem 'jquery-rails' # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks gem 'turbolinks', '~> 5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.5' # Use Redis adapter to run Action Cable in production # gem 'redis', '~> 3.0' # Use ActiveModel has_secure_password # gem 'bcrypt', '~> 3.1.7' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platform: :mri end group :development do # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. gem 'web-console', '>= 3.3.0' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] #bootstrap gem 'bootstrap-sass', '~> 3.4.1' #デバイス gem 'devise', '~>4.2' #Gravatar gem 'gravtastic' #フラッシュメッセージ gem 'toastr-rails', '~> 1.0' #日本語化 gem 'rails-i18n' #画像アップロード gem 'paperclip', '~> 5.1.0' #googleマップ gem 'geocoder', '~> 1.4'
コマンド
bundle
コマンド
rails g migration AddFieldsToRoom latitude:float longitude:float
コマンド マイグレーション
rails db:migrate
記述追加 app\models\room.rb(5行目)
geocoded_by :address after_validation :geocode, if: :address_changed?
app\models\room.rb
class Room < ApplicationRecord belongs_to :user has_many :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 def cover_photo(size) if self.photos.length > 0 self.photos[0].image.url(size) else "blank.jpg" end end end
GoogleマップAPIの埋め込み
取得したキーを「key=」から「&callback」の間に埋め込んで下さい。
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBojDcZmScBkIOISjoYREjgid99iZUL2Tk&callback=initMap" type="text/javascript"></script>
このscriptタグをサイトに埋め込みます。
記述追加 app\views\rooms\show.html.erb(126行目)
<!-- GOOGLE マップ --> <div class="row"> <div id="map" style="width: 100%; height: 400px"></div> <script src="https://maps.googleapis.com/maps/api/js"></script> <script> function initialize() { var location = {lat: <%= @room.latitude %>, lng: <%= @room.longitude %>}; var map = new google.maps.Map(document.getElementById('map'), { center: location, zoom: 14 }); var marker = new google.maps.Marker({ position: location, map: map }); var infoWindow = new google.maps.InfoWindow({ content: '<div id="content"><%= image_tag @room.cover_photo(:medium) %></div>' }); infoWindow.open(map, marker); } google.maps.event.addDomListener(window, 'load', initialize); </script> <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBojDcZmScBkIOISjoYREjgid99iZUL2Tk&callback=initMap" type="text/javascript"></script> </div> <hr/> <!-- 近くのお部屋を検索 --> <div class="row"> <h3>お近くのお部屋</h3> <% for room in @room.nearbys(10) %> <div class="col-md-4"> <div class="panel panel-default"> <div class="panel-heading preview"> <%= image_tag room.cover_photo(:medium) %> </div> <div class="panel-body"> <%= link_to room.listing_name, room %><br/> (距離:<%= room.distance.round(2) %> Km) </div> </div> </div> <% end %> </div>
app\views\rooms\show.html.erb
<!-- 写真 --> <div class="row"> <div class="col-md-12"> <%= image_tag @room.cover_photo(nil), width: "100%" %> </div> </div> <br/> <div class="row"> <!-- 左パネル --> <div class="col-md-8"> <!-- お部屋の名前 --> <div class="row"> <div class="col-md-8"> <h1><%= @room.listing_name %></h1> <%= @room.address %> </div> <div class="col-md-4 text-center"> <%= image_tag @room.user.gravatar_url, class: "img-circle avatar-large" %><br/><br/> <%= @room.user.fullname %> </div> </div> <hr/> <!-- 部屋のインフォメーション --> <div class="row text-babu"> <div class="row text-center row-space-1"> <div class="col-md-3"> <i class="fa fa-home fa-2x"></i> </div> <div class="col-md-3"> <i class="fa fa-user-circle-o fa-2x"></i> </div> <div class="col-md-3"> <i class="fa fa-bed fa-2x"></i> </div> <div class="col-md-3"> <i class="fa fa-bath fa-2x"></i> </div> </div> <div class="row text-center"> <div class="col-md-3"><%= @room.home_type %></div> <div class="col-md-3"><%= pluralize(@room.accommodate, "人宿泊可能") %></div> <div class="col-md-3"><%= pluralize(@room.bed_room, "台") %></div> <div class="col-md-3"><%= pluralize(@room.bath_room, "部屋") %></div> </div> </div> <hr/> <!-- 詳細 --> <div class="row"> <div class="col-md-12"> <h3>お部屋の詳細</h3> <p><%= @room.summary %></p> </div> </div> <hr/> <!-- アメニティ --> <div class="row"> <div class="col-md-3"> <h4>アメニティ</h4> </div> <div class="col-md-9"> <div class="row"> <div class="col-md-6"> <ul class="amenities"> <li class="<%= 'text-line-through' if !@room.is_tv %>">テレビ</li> <li class="<%= 'text-line-through' if !@room.is_kitchen %>">キッチン</li> <li class="<%= 'text-line-through' if !@room.is_internet %>">インターネット</li> </ul> </div> <div class="col-md-6"> <ul class="amenities"> <li class="<%= 'text-line-through' if !@room.is_heating %>">暖房</li> <li class="<%= 'text-line-through' if !@room.is_air %>">エアコン</li> </ul> </div> </div> </div> </div> <hr/> <!-- カルーセル表示 --> <div class="row"> <% if @photos.length > 0 %> <div id="myCarousel" class="carousel slide" data-ride="carousel"> <!-- 表示 --> <ol class="carousel-indicators"> <% @photos.each do |photo| %> <li data-target="#myCarousel" data-slide-to="<%= photo.id %>"></li> <% end %> </ol> <!-- スライド --> <div class="carousel-inner"> <% @photos.each do |photo| %> <div class="item <%= 'active' if photo.id == @photos[0].id %>"> <%= image_tag photo.image.url() %> </div> <% end %> </div> <!-- 左右移動 --> <a class="left carousel-control" href="#myCarousel" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left"></span> <span class="sr-only">戻る</span> </a> <a class="right carousel-control" href="#myCarousel" data-slide="next"> <span class="glyphicon glyphicon-chevron-right"></span> <span class="sr-only">次へ</span> </a> </div> <% end %> </div> <hr/> <!-- GOOGLE マップ --> <div class="row"> <div id="map" style="width: 100%; height: 400px"></div> <script src="https://maps.googleapis.com/maps/api/js"></script> <script> function initialize() { var location = {lat: <%= @room.latitude %>, lng: <%= @room.longitude %>}; var map = new google.maps.Map(document.getElementById('map'), { center: location, zoom: 14 }); var marker = new google.maps.Marker({ position: location, map: map }); var infoWindow = new google.maps.InfoWindow({ content: '<div id="content"><%= image_tag @room.cover_photo(:medium) %></div>' }); infoWindow.open(map, marker); } google.maps.event.addDomListener(window, 'load', initialize); </script> <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBojDcZmScBkIOISjoYREjgid99iZUL2Tk&callback=initMap" type="text/javascript"></script> </div> <hr/> <!-- 近くのお部屋を検索 --> <div class="row"> <h3>お近くのお部屋</h3> <% for room in @room.nearbys(10) %> <div class="col-md-4"> <div class="panel panel-default"> <div class="panel-heading preview"> <%= image_tag room.cover_photo(:medium) %> </div> <div class="panel-body"> <%= link_to room.listing_name, room %><br/> (距離:<%= room.distance.round(2) %> Km) </div> </div> </div> <% end %> </div> </div> <!-- 右パネル --> <div class="col-md-4"> <!-- 予約フォーム --> </div> </div>
「config\initializers」フォルダに「geocoder.rb」ファイルを新規作成します。
config\initializers\geocoder.rb(新規作成したファイル)
Geocoder.configure( units: :km )
ブラウザ確認
お部屋を登録するときに住所を入力すると自動で位置情報が保存されます。(Geocordingの機能)
ただし、日本の住所に対する変換が貧弱なので「北海道札幌市中央区」くらいまでしか認識してくれません。
http://localhost:3000/rooms/1/location
住所を入力して位置情報が更新されるか確かめてみます。
部屋を2つ以上登録して公開します。
http://localhost:3000/rooms/new
お部屋のページを確認します。
http://localhost:3000/rooms/1