| 28 | 予約モデルの実装 << [ホーム] >> | 30 | jQuery日付ピッカー
「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' %>」の記述追加(181行目)
<div class="row" style="margin-left: 10px; margin-right: 10px;"> <!-- 左パネル --> <div class="col-md-8"> <!-- 写真 --> <div class="row" style="margin-top: 1rem;"> <div class="col-md-11"> <div class="card" style="width: 100%;"> <div class="card-body"> <%= image_tag room_cover(@room), style: "width: 100%" %> </div> </div> </div> </div> <br/> <!-- 部屋の名前 --> <div class="row"> <div class="col-md-11"> <div class="card"> <div class="card-body"> <h3 class="badge bg-info" style="font-size: 2rem; color: white;"><%= @room.listing_name %></h3><br/> <label>Address</label> <div style="font-size: 1.5rem; margin-top: -1rem;"><%= @room.address %></div> <div class="text-right"> <%= image_tag avatar_url(@room.user), class: "bd-placeholder-img figure-img img-fluid rounded-pill", style: "width: 40px; height: 30px;" %> <%= @room.user.full_name %> </div> </div> </div> </div> </div> <br/> <!-- 部屋のインフォメーション --> <div class="row text-babu"> <div class="col-md-11"> <div class="card"> <div class="card-body"> <div class="row text-center row-space-1"> <div class="col-md-3"> <i class="fas fa-home fa-2x" style="color: cadetblue"></i><br/> <%= @room.home_type %> </div> <div class="col-md-3"> <i class="fas fa-user fa-2x" style="color: cadetblue"></i><br/> <%= pluralize(@room.accommodate, "人宿泊可能") %> </div> <div class="col-md-3"> <i class="fas fa-bed fa-2x" style="color: cadetblue"></i><br/> <%= pluralize(@room.bed_room, "台") %> </div> <div class="col-md-3"> <i class="fas fa-door-closed fa-2x" style="color: cadetblue"></i><br/> <%= pluralize(@room.bath_room, "部屋") %> </div> </div> </div> </div> </div> </div> <br/> <!-- 詳細 --> <div class="row"> <div class="col-md-11"> <div class="card"> <div class="card-body"> <h4 class="badge bg-primary" style="font-size: 1.5rem; color: white;">部屋の詳細</h4> <p><font style="font-size: 1.2rem;"><%= @room.description %></font></p> </div> </div> </div> </div> <br/> <!-- アメニティ --> <div class="row"> <div class="col-md-11"> <div class="card"> <div class="card-body"> <h4 class="badge bg-warning" style="font-size: 1.5rem; color: white;">アメニティ</h4> <div class="col-md-8"> <div class="row"> <div class="col-md-5"> <ul class="amenities"> <li class="<%= 'text-line-through' if !@room.is_tv %>"><span style="color: black;"><i class="fas fa-tv"></i> テレビ</span></li> <li class="<%= 'text-line-through' if !@room.is_kitchen %>"><span style="color: black;"><i class="fas fa-blender"></i> キッチン</span></li> <li class="<%= 'text-line-through' if !@room.is_internet %>"><span style="color: black;"><i class="fas fa-wifi"></i> インターネット</span></li> </ul> </div> <div class="col-md-5"> <ul class="amenities"> <li class="<%= 'text-line-through' if !@room.is_heating %>"><span style="color: black;"><i class="fab fa-hotjar"></i> 暖房</span></li> <li class="<%= 'text-line-through' if !@room.is_air %>"><span style="color: black;"><i class="fas fa-temperature-low"></i> エアコン</span></li> </ul> </div> </div> </div> </div> </div> </div> </div> <br/> <!-- レビュー --> <br/> <!-- カルーセル表示 --> <div class="row"> <div class="col-md-11"> <div id="carouselExampleControls" class="carousel slide" data-ride="carousel"> <% if @photos.length > 0 %> <ol class="carousel-indicators"> <% @photos.each do |photo| %> <li data-target="#carouselExampleIndicators" data-slide-to="<%= photo.id %>" class="<%= 'active' if photo.id == @photos[0].id %>"></li> <% end %> </ol> <div class="carousel-inner"> <% @photos.each do |photo| %> <div class="carousel-item <%= 'active' if photo.id == @photos[0].id %>"> <%= image_tag url_for(photo), class: "bd-placeholder-img bd-placeholder-img-lg d-block w-100", width: "100%" %> </div> <% end %> <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev"> <span class="carousel-control-prev-icon" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next"> <span class="carousel-control-next-icon" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> <% end %> </div> </div> </div> <hr/> <!-- googleマップ --> <div class="col-md-11" style="margin-top: 30px;"> <div id="map" style="width: 100%; height: 600px"></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(@room), style: "width: 300px;", :alt => '' %></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=AIzaSyDoAh6S8kEpArgzG&callback=initMap" type="text/javascript"></script> </div> <!-- 近くのお部屋を検索 --> <h3 class="badge bg-primary" style="font-size: 1.5rem; color: white; margin-top: 3rem; margin-left: 2rem;"> 近くのお部屋 </h3> <div class="row" style="margin-left: 30px; margin-right: 30px;"> <% for room in @room.nearbys(10) %> <div class="col-6 col-md-3"> <%= image_tag room_cover(room), style: "width: 100%; height: 180;" %> <h5 class="card-title badge bg-info"><%= link_to room.listing_name, room, data: { turbolinks: false}, style: "font-size: 1.0rem; color: white; text-decoration: none;" %></h5> <footer>(距離:<%= room.distance.round(2) %> Km)</footer> </div> <% end %> </div> </div> </div> <!-- 右パネル --> <div class="col-md-4" style="margin-top: 1rem;"> <!-- 予約フォーム --> <%= render 'reservations/form' %> </div>
「app\views」フォルダに「reservations」フォルダを新規作成します。
作成した「reservations」フォルダに「_form.html.erb」ファイルを新規作成します。
app\views\reservations\_form.html.erb(新規作成したファイル)
<%= form_for([@room, @room.reservations.new]) do |f| %> <div class="card" style="width: 24rem; margin-left: -70px;"> <div class="card-header"> </div> <div class="card-body"> <form> <div class="form-row"> <div class="col"> <%= f.text_field :start_date, readonly: true, placeholder: "チェックイン", class: "form-control" %> </div> <div class="col"> <%= f.text_field :end_date, readonly: true, placeholder: "チェックアウト", class: "form-control" %> </div> </div> </form> <br/> <%= f.submit "予約する", id: "btn_book", class: "btn btn-danger btn-block", disabled: true %> </div> </div> <% end %>
ブラウザ確認
http://localhost:3000/rooms/1
↓↓クリックして頂けると励みになります。
| 28 | 予約モデルの実装 << [ホーム] >> | 30 | jQuery日付ピッカー