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

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

Ruby on Rails6.0 | 空き部屋を登録・予約・決済できるWebサイトを作成する 25 | Googleマップ

[24]写真カルーセル表示<< [ホームに戻る] >> [26]Facebook認証


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


記述追加 GemFile(73行目)

#googleマップ
gem 'geocoder', '~> 1.4'



GemFile

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.6'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# 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.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '~> 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

# Bulma
gem 'bulma-rails', '~> 0.7.4'
gem 'bulma-extensions-rails', '~> 1.0.30'

# デバイス
gem 'devise'

# 日本語化
gem 'rails-i18n'

# アマゾンS3
gem "aws-sdk"

# アクションテキスト画像表示
gem "mini_magick"
gem 'image_processing', '~> 1.2'

#googleマップ
gem 'geocoder', '~> 1.4'



コマンド
bundle


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


コマンド マイグレーション
rails db:migrate


記述追加 app\models\room.rb(8行目)

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



app\models\room.rb

class Room < ApplicationRecord

  belongs_to :user

  has_many_attached :photos
  has_rich_text :description

  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



GoogleマップAPIの埋め込み
取得したキーを「key=」から「&callback」の間に埋め込んで下さい。

<script async defer src="https://maps.googleapis.com/maps/api/js?key=ここにご自分のAPIキーを埋め込みます&callback=initMap" type="text/javascript"></script>



このscriptタグをサイトに埋め込みます。


1.記述追加 app\views\rooms\show.html.erb(188行目)

<!-- 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" class="image is-128x128"><%= image_tag room_cover(@room) %></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=ここにご自分のAPIキーを埋め込みます&callback=initMap" type="text/javascript"></script>
</div>



2.記述追加 app\views\rooms\show.html.erb(227行目)

<!-- 近くのお部屋を検索 -->
<div class="row">
    <h3>お近くのお部屋</h3>
    <br/>
    <% for room in @room.nearbys(10) %>
        <div class="col-md-4">

            <div class="image is-128x128">
                <%= image_tag room_cover(room) %>                    
            </div>
            <span>
            <%= link_to room.listing_name, room %><br/>
            (距離:<%= room.distance.round(2) %> Km)
            </span>
        </div>
    <% end %>
</div>



app\views\rooms\show.html.erb

<section class="section">
    <div class="container">
        <div class="columns">

            <!-- 写真 -->
            <div class="card">
                <div class="card-content">
                    <div class="content">
                        <%= image_tag room_cover(@room) %>
                    </div>
                </div>
            </div>
            <br/>

        </div>
    </div>
</section>

<section class="section">
    <div class="container">
        <div class="columns">

            <!-- 左側 -->
            <div class="column is-two-thirds">
                <div class="columns is-multiline">

                    <div class="column">
                        <div class="card">
                            <div class="card-content">

                                
                                <div class="box">
                                    <article class="media">

                                        <div class="media-content">
                                            <div class="content">

                                                <!-- お部屋の名前 -->
                                                <div class="row">
                                                    <div class="col-md-8">
                                                        <h1><%= @room.listing_name %></h1>
                                                        <h2><%= @room.address %></h2>
                                                    </div>
                                                 
                                                </div>
                                            </div>
                                        </div>
                                    </article>
                                </div>

                                <div class="box">
                                    <article class="media">

                                        <div class="media-content">
                                            <div class="content">
                                                <span class="title is-5"><%= @room.user.full_name %></span>
                                                <figure class="image is-96x96">
                                                    <%= image_tag avatar_url(@room.user), class: "is-rounded" %>
                                                </figure>
                                            </div>

                                        </div>
                                    </article>
                                </div>

                                <div class="box">
                                    <article class="media">

                                        <div class="media-content">
                                            <div class="content">

                                                <!-- 部屋のインフォメーション -->
                                                <div style="white-space: nowrap">

                                                    <span class="col-md-3">
                                                        <i class="fas fa-home fa-3x" style="color: #1dbf73"></i>
                                                        <span class="col-md-3"><%= @room.home_type %></span>
                                                    </span>
                                                    &nbsp;&nbsp;&nbsp;
                                                    <span class="col-md-3">
                                                        <i class="fas fa-user fa-3x" style="color: #1dbf73"></i>
                                                        <span class="col-md-3"><%= pluralize(@room.accommodate, "人") %></span>
                                                    </span>
                                                    &nbsp;&nbsp;&nbsp;
                                                    <span class="col-md-3">
                                                        <i class="fas fa-bed fa-3x" style="color: #1dbf73"></i>
                                                        <span class="col-md-3"><%= pluralize(@room.bed_room, "台") %></span>
                                                    </span>
                                                    &nbsp;&nbsp;&nbsp;
                                                    <span class="col-md-3">
                                                        <i class="fas fa-bath fa-3x" style="color: #1dbf73"></i>
                                                        <span class="col-md-3"><%= pluralize(@room.bath_room, "部屋") %></span>
                                                    </span>
                                                </div>

                                            </div>

                                        </div>
                                    </article>
                                </div>

                                <!-- お部屋の詳細 -->
                                <div class="box">
                                    <article class="media">

                                        <div class="media-content">
                                            <div class="content">
                                                <h3>お部屋の詳細</h3>
                                                <p><%= @room.description %></p>

                                            </div>

                                        </div>
                                    </article>
                                </div>

                                <!-- アメニティー -->
                                <div class="box">
                                    <article class="media">

                                        <div class="media-content">
                                            <div class="content">

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


                                            </div>

                                        </div>
                                    </article>
                                </div>


                            </div>
                        </div>                        
                    </div>

                    <!-- カルーセル表示 -->
                    <div class="column is-full">   

                        <div class="card">
                            <div class="card-content">
                                <div class="hero-carousel" id="carousel-photo">
                                    <% @room.photos.each do |photo| %>
                                        <div class="carousel-item has-background image is-16by9">
                                            <%= image_tag url_for(photo), class: "is-background", width: "100%" %>
                                        </div>
                                    <% end %>
                                </div>
                            </div>
                        </div>

                    </div>

             
                    <div class="column">
                        <div class="card">
                            <div class="card-content">

                                <!-- googleマップ -->
                                <div class="box">
                                    <article class="media">

                                        <div class="media-content">
                                            <div class="content">

                                                <!-- 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" class="image is-128x128"><%= image_tag room_cover(@room) %></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=ここにご自分のAPIキーを埋め込みます&callback=initMap" type="text/javascript"></script>
                                                </div>

                                            </div>

                                        </div>
                                    </article>
                                </div>

                                <!-- 近くのお部屋 -->
                                <div class="box">
                                    <article class="media">

                                        <div class="media-content">
                                            <div class="content">

                                                <!-- 近くのお部屋を検索 -->
                                                <div class="row">
                                                    <h3>お近くのお部屋</h3>
                                                    <br/>
                                                    <% for room in @room.nearbys(10) %>
                                                        <div class="col-md-4">

                                                            <div class="image is-128x128">
                                                                <%= image_tag room_cover(room) %>                    
                                                            </div>
                                                            <span>
                                                            <%= link_to room.listing_name, room %><br/>
                                                            (距離:<%= room.distance.round(2) %> Km)
                                                            </span>
                                                        </div>
                                                    <% end %>
                                                </div>
                                                
                                            </div>
                                        </div>
                                    </article>
                                </div>

 
                            </div>
                        </div>                        
                    </div>

                </div>
            </div>


            <!-- 右側 -->
            <div class="column">
                <div class="columns is-multiline">

                    <!-- 予約 -->
                    <div class="column is-full">
                        <div class="card">
                            <div class="card-content">
                                <div class="media">

                                </div>
                            </div>
                        </div>

                    </div>


                </div>
            </div>
            
        </div>
    </div>
</section>


<script>
    BulmaCarousel.attach('#carousel-photo', {
        slidesToScroll: 1,
        slidesToShow: 1
    });

    $(document).ready(function() {
        $('#tabs li').on('click', function() {
            var type = $(this).data('tab');

            $('#tabs li').removeClass('is-active');
            $(this).addClass('is-active');

            $('.tab-content').hide();
            $('#tab-' + type).show();
        }) 
    })

</script>



「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

マップ表示の確認
マップ表示の確認



[24]写真カルーセル表示<< [ホームに戻る] >> [26]Facebook認証