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

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

Ruby on Rails6.0 | 空き部屋を登録・予約・決済できるWebサイトを作成する 30 | 予約コントローラとビュー

「app\controllers」フォルダに「reservations_controller.rb」ファイルを新規作成します。


app\controllers\reservations_controller.rb(新規作成したファイル)

class ReservationsController < ApplicationController
    before_action :authenticate_user!
  
    def create
      room = Room.find(params[:room_id])
  
      if current_user == room.user
        flash[:alert] = "オーナーが予約することはできません。"
      else
  
          start_date = Date.parse(reservation_params[:start_date])
          end_date = Date.parse(reservation_params[:end_date])
          days = (end_date - start_date).to_i + 1
  
          @reservation = current_user.reservations.build(reservation_params)
          @reservation.room = room
          @reservation.price = room.price
          @reservation.total = room.price * days
          @reservation.save
  
          flash[:notice] = "予約が完了しました。"
        end
        redirect_to room
    end
  
  
    private
      def reservation_params
        params.require(:reservation).permit(:start_date, :end_date)
      end
  end
  



記述追加 app\views\rooms\show.html.erb
「<%= render 'reservations/form' %>」の記述追加(235行目)

<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">
                                    <!-- 予約フォーム -->
                                    <%= render 'reservations/form' %>                                
                                </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>



「app\views」フォルダに「reservations」フォルダを新規作成します。
作成した「reservations」フォルダに「_form.html.erb」ファイルを新規作成します。



app\views\reservations\_form.html.erb(新規作成したファイル)

<%= form_for([@room, @room.reservations.new]) do |f| %>

    <div class="field is-horizontal">
        <div class="field-body">
            <div class="field">
            <p class="control is-expanded has-icons-left">
                <%= f.text_field :start_date, readonly: true, placeholder: "イン", class: "input is-primary is-rounded" %>
                <span class="icon is-small is-left">
                <i class="far fa-calendar-alt"></i>
                </span>
            </p>
            </div>
            <div class="field">
            <p class="control is-expanded has-icons-left has-icons-right">
                <%= f.text_field :end_date, readonly: true, placeholder: "アウト", class: "input is-primary is-rounded" %>
                <span class="icon is-small is-left">
                <i class="far fa-calendar-alt"></i>
                </span>

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

    <%= f.submit "予約する", class: "button is-danger is-fullwidth m-t-10 m-b-10"  %>
<% end %>



ブラウザ確認
http://localhost:3000/rooms/1

予約フォーム
予約フォーム