| 31 |予約フォームの実装 << [ホーム] >> | 33 |レビューの実装
宿泊者(ゲスト)の予約確認ページを作成します。
記述追加 app\controllers\reservations_controller.rb(26行目)
def your_trips @trips = current_user.reservations.order(start_date: :asc) end
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 def your_trips @trips = current_user.reservations.order(start_date: :asc) end private def reservation_params params.require(:reservation).permit(:start_date, :end_date) end end
記述追加 config\routes.rb
「get '/your_trips' => 'reservations#your_trips'」の記述追加(14行目)
Rails.application.routes.draw do # ルートを app\views\pages\home.html.erb に設定 root 'pages#home' devise_for :users, path: '', path_names: {sign_up: 'register', sign_in: 'login', edit: 'profile', sign_out: 'logout'}, controllers: {registrations: 'registrations'} get 'pages/home' get '/dashboard', to: 'users#dashboard' get '/users/:id', to: 'users#show' get '/your_trips' => 'reservations#your_trips' post '/users/edit', to: 'users#update' resources :rooms, except: [:edit] do member do get 'listing' get 'pricing' get 'description' get 'photo_upload' get 'amenities' get 'location' get 'preload' get 'preview' delete :delete_photo post :upload_photo end resources :reservations, only: [:create] end # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end
「app\views\reservations」フォルダに「your_trips.html.erb」ファイルを新規作成します。
app\views\reservations\your_trips.html.erb(新規作成したファイル)
<div class="row" style="margin-top: 50px; margin-left: 2rem;"> <div class="card"> <div class="bg-dark"> <h3 style="margin-top: 30px; font-size: 1.5rem; color: white; position: relative; bottom: 0.7rem; left: 3rem;">予約内容 Reservation contents</h3> </div> <table class="table table-striped text-center"> <thead> <tr> <th>申し込み日</th> <th>ステータス</th> <th>部屋</th> <th>ホスト</th> <th>日程</th> <th>泊数</th> <th>料金</th> <th>アクション</th> </tr> </thead> <tbody> <% if @trips.blank? %> <tr> <td colspan="7"><h5>表示できる予約はありません。</h5></td> </tr> <% end %> <% @trips.each do |trip| %> <tr> <td><%= I18n.l(trip.created_at, format: :full_date) %></td> <!-- ステータス --> <td> </td> <td> <%= link_to room_path(trip.room), data: { turbolinks: false} do %> <%= image_tag room_cover(trip.room), style: "width: 60px;" %><br/> <span class="badge bg-info" style="color: white;"><%= trip.room.listing_name %></span> <% end %> </td> <td> <%= link_to user_path(trip.room.user), class: "tootip" do %> <%= image_tag avatar_url(trip.room.user), style: "width: 50px;", class: "bd-placeholder-img figure-img img-fluid rounded-pill" %><br/> <span class="badge bg-info" style="color: white;"><%= trip.room.user.full_name %></span> <% end %> </td> <td> 宿泊日:<%= I18n.l(trip.start_date, format: :full_date) %><br/> ご出発:<%= I18n.l(trip.end_date, format: :full_date) %> </td> <td><%=trip.total/trip.price %>泊</td> <td><%= number_to_currency(trip.total) %></td> <!-- アクション --> <td> </td> </tr> <% end %> </tbody> </table> </div> </div>
ブラウザ確認
宿泊者の予約確認ページです。
http://localhost:3000/your_trips
お部屋登録者(ホスト)の予約確認ページを作成します。
記述追加 app\controllers\reservations_controller.rb(30行目)
def your_reservations @rooms = current_user.rooms end
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 def your_trips @trips = current_user.reservations.order(start_date: :asc) end def your_reservations @rooms = current_user.rooms end private def reservation_params params.require(:reservation).permit(:start_date, :end_date) end end
記述追加 config\routes.rb
15行目に「get '/your_reservations' => 'reservations#your_reservations'」の記述を追加
Rails.application.routes.draw do # ルートを app\views\pages\home.html.erb に設定 root 'pages#home' devise_for :users, path: '', path_names: {sign_up: 'register', sign_in: 'login', edit: 'profile', sign_out: 'logout'}, controllers: {registrations: 'registrations'} get 'pages/home' get '/dashboard', to: 'users#dashboard' get '/users/:id', to: 'users#show', as: 'user' get '/your_trips' => 'reservations#your_trips' get '/your_reservations' => 'reservations#your_reservations' post '/users/edit', to: 'users#update' resources :rooms, except: [:edit] do member do get 'listing' get 'pricing' get 'description' get 'photo_upload' get 'amenities' get 'location' get 'preload' get 'preview' delete :delete_photo post :upload_photo end resources :reservations, only: [:create] end # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end
「app\views\reservations」フォルダに「your_reservations.html.erb」ファイルを新規作成します。
app\views\reservations\your_reservations.html.erb(新規作成したファイル)
<div class="row" style="margin-top: 50px; margin-left: 2rem;"> <div class="card"> <div class="bg-danger"> <h3 style="margin-top: 30px; font-size: 1.5rem; color: white; position: relative; bottom: 0.7rem; left: 3rem;">受注 Order received</h3> </div> <table class="table table-striped text-center"> <thead> <tr> <th>申し込み日</th> <th>ステータス</th> <th>部屋</th> <th>ゲスト</th> <th>日程</th> <th>泊数</th> <th>料金</th> <th>アクション</th> </tr> </thead> <tbody> <% if @rooms.blank? %> <tr> <td colspan="7"><h5>表示できる受注はありません。</h5></td> </tr> <% end %> <% @rooms.each do |room| %> <% room.reservations.each do |reservation| %> <tr> <td><%= I18n.l(reservation.created_at, format: :full_date) %></td> <!-- ステータス --> <td> </td> <td> <%= link_to room_path(reservation.room), data: { turbolinks: false} do %> <%= image_tag room_cover(reservation.room), style: "width: 60px;" %><br/> <span class="badge bg-dark" style="color: white;"><%= reservation.room.listing_name %></span> <% end %> </td> <td> <%= link_to user_path(reservation.user), class: "tootip" do %> <%= image_tag avatar_url(reservation.user), style: "width: 50px;", class: "bd-placeholder-img figure-img img-fluid rounded-pill" %><br/> <span class="badge bg-dark" style="color: white;"><%= reservation.user.full_name %></span> <% end %> </td> <td> 宿泊日:<%= I18n.l(reservation.start_date, format: :full_date) %><br/> ご出発:<%= I18n.l(reservation.end_date, format: :full_date) %> </td> <td><%=reservation.total/reservation.price %>泊</td> <td><%= number_to_currency(reservation.total) %></td> <!-- アクション --> <td> </td> </tr> <% end %> <% end %> </tbody> </table> </div> </div>
ブラウザ確認
お部屋登録者(ホスト)用の予約確認ページです。
http://localhost:3000/your_reservations
ナビゲーションバーのリンク部分を追加します。
1.49行目に「<%= link_to "受注管理", your_reservations_path, class: "btn btn-danger", style: "margin-left: 0.5rem;" %>」
2.57行目に「<%= link_to "ご予約の確認", your_trips_path, class: "btn btn-dark", style: "margin-left: 0.5rem;" %>」
記述追加 app\views\shared\_navbar.html.erb
<nav class="navbar navbar-expand-lg navbar-dark bg-dark" style="z-index: 5;"> <a class="navbar-brand" href="/"><h1 class="navh1"><font style="font-size: 1.2rem"><b>民泊予約サイト</font> <font style="font-size: 0.9rem">Private lodging reservation site</b></font></h1></a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse justify-content-end" id="navbarNavDropdown"> <ul class="navbar-nav"> <!-- もしログインしていなかったら--> <% if (!user_signed_in?) %> <li class="nav-item" style="margin-right: 20px; margin-bottom: 5px;"> <%= link_to "まずはユーザ登録 Sign up", new_user_registration_path, class: "btn btn-danger btn-sm" %> </li> <li class="nav-item"> <%= link_to "ユーザ登録がお済みの方はこちら login", new_user_session_path, class: "btn btn-info btn-sm", style: "margin-right: 80px;" %> </li> <!-- ログインしていたら --> <% else %> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <figure style="position:relative; top: 0.2rem;" class="avatar <%= current_user.status ? "online" : "offline" %>"></figure> <%= image_tag avatar_url(current_user), class: "bd-placeholder-img figure-img img-fluid rounded-pill", style: "width: 40px; height: 30px; margin-top: 0.5rem;" %> <div class="btn btn-light bg-light text-dark"><%= current_user.full_name %></div> </a> <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> <span class="dropdown-item"><i class="fas fa-user-edit"></i> <%= link_to "ユーザ登録情報編集", edit_user_registration_path, class: "btn btn-warning" %></span> <span class="dropdown-item"><i class="fas fa-sign-out-alt"></i> <%= link_to "ログアウト", destroy_user_session_path, method: :delete, class: "btn btn-danger" %></span> </div> </li> <% end %> </ul> </div> </nav> <% if (user_signed_in?) %> <nav class="navbar navbar-expand-lg navbar-light bg-info" style="z-index: 3;"> <div class="collapse navbar-collapse justify-content-end" id="navbarNavDropdown"> <ul class="navbar-nav mr-auto"> <li class="nav-item" style="margin-top: 7px;"> <i class="fas fa-tachometer-alt" style="color: white;"></i> <%= link_to 'ダッシュボード Dashboard', dashboard_path, class: "btn btn-light" %> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <i class="fas fa-hospital-symbol" style="color: white;"></i> <div class="btn btn-light bg-light text-dark">ホスト Host</div> </a> <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> <span class="dropdown-item"><i class="fas fa-edit"></i></i><%= link_to "部屋を新規登録", new_room_path, class: "btn btn-primary", style: "margin-left: 0.5rem;" %></span> <span class="dropdown-item"><i class="far fa-list-alt"></i><%= link_to "部屋管理", rooms_path, class: "btn btn-success", style: "margin-left: 0.5rem;" %></span> <span class="dropdown-item"><i class="far fa-list-alt"></i><%= link_to "受注管理", your_reservations_path, class: "btn btn-danger", style: "margin-left: 0.5rem;" %></span> </div> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <i class="fas fa-user-friends" style="color: white;"></i> <div class="btn btn-light bg-light text-dark">ゲスト Guest</div> </a> <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> <span class="dropdown-item"><i class="far fa-list-alt"></i><%= link_to "ご予約の確認", your_trips_path, class: "btn btn-dark", style: "margin-left: 0.5rem;" %></span> </div> </li> </ul> </div> </nav> <% end %>
プロフィールページを修正していきます。
記述追加 app\controllers\users_controller.rb
「show()」メソッドに「@rooms = @user.rooms」の記述を追加してます。(10行目)
class UsersController < ApplicationController before_action :authenticate_user! def dashboard end def show @user = User.find(params[:id]) @rooms = @user.rooms end def update @user = current_user if @user.update_attributes(current_user_params) flash[:notice] = "保存しました" else flash[:alert] = "更新できません" end redirect_to dashboard_path end private def current_user_params params.require(:user).permit(:about, :status, :avatar) end end
記述追加 app\views\users\show.html.erb(72行目から94行目)
<div class="row" style="margin: 20px;"> <!-- 左側 --> <div class="col-4"> <div class="card"> <div class="card-body"> <!-- アバター --> <%= image_tag avatar_url(@user), class: "img-fluid img-thumbnail rounded-pill" %> <!-- ユーザー名 --> <div class="mx-auto" style="text-align: center;"> <h5 class="card-title btn-block"> <br/> <!-- オンラインステータス --> <span style="position:relative; top: 0.8rem; left: 0.5rem;"> <% if @user.status %> <span class="badge rounded-pill bg-success text-light">Online</span> <% else %> <span class="badge rounded-pill bg-secondary text-light">Offline</span> <% end %> </span> <%= @user.full_name %> </h5> <%= @user.about %> </div> <br/> <!-- 自己紹介 --> <div style="margin-left: 20px;"> <div class="collapse" id="collapseExample2"> <div class="card card-body" style="width: 16rem;"> <%= form_for :user, url: users_edit_url(current_user), action: :update, method: :post do |f| %> <%= f.text_area :about, autofocus: true, autocomplete: 'form'%> <br/> <br/> <%= f.submit "保存", class: "btn btn-outline-info" %> <% end %> </div> </div> <div class="mx-auto" style="margin-top: 1rem; text-align: right;"> <%= l(current_user.created_at, format: :long) %> </div> </div> </div> </div> </div> <!-- 右側 --> <div class="col-8"> <!-- お知らせ --> <div class="card"> <div class="card-header"> お知らせ </div> <div class="card-body"> <h5 class="card-title"></h5> <p class="card-text"></p> </div> </div> <br/> <!-- 登録しているお部屋 --> <!-- 登録しているお部屋 --> <div class="card"> <div class="card-header bg-dark text-light"> <%= @user.full_name %>さんが登録しているお部屋(<%= @rooms.length %>) </div> <div class="card-body"> <div class="row"> <% @user.rooms.each do |room| %> <% if room.active? %> <div class="col-6 col-md-4" style="margin-bottom: 20px;"> <%= link_to room_path(room), data: { turbolinks: false} do %> <%= image_tag room_cover(room), style: "width: 100%; height: 180;" %> <% end %> <%= link_to room.listing_name, room_path(room), data: { turbolinks: false}, class: "badge bg-info text-light" %><br/> <div class="badge bg-secondary text-light">住所:<%= room.address %></div><br/> <footer class="badge bg-warning" style="font-size: 0.9rem;"><%= number_to_currency(room.price) %></footer> </div> <% end %> <% end %> </div> </div> </div> <br/> <!-- レビュー --> <div class="card"> <div class="card-header"> レビュー </div> <div class="card-body"> </div> </div> <br/> </div> </div>
ブラウザ確認
アドレスの数字のところは表示したいユーザのidを入れてください。
http://localhost:3000/users/3
ダッシュボードページの更新も行います。
記述更新 app\views\users\dashboard.html.erb(102行目から124行目)
<div class="row" style="margin: 20px;"> <!-- 左側 --> <div class="col-4"> <div class="card"> <div class="card-body"> <!-- アバター --> <%= image_tag avatar_url(current_user), class: "img-fluid img-thumbnail rounded-pill" %> <!-- 画像アップロードボタン --> <div class="mx-auto" style="text-align: center;"> <h5 class="card-title btn-block" style="margin-left: 15px; margin-top: 10px;"><%= current_user.full_name %></h5> <%= current_user.about %> </div> <br/> <a data-toggle="collapse" href="#collapseExample3" role="button" aria-expanded="false" aria-controls="collapseExample3" style="text-decoration: none;"> <div> <strong> <button type="button" class="btn btn-info btn-block"><i class="fas fa-upload"></i>アバター画像アップロード<br/> Avatar image upload</button> </strong> </a> <br/> <div class="collapse" id="collapseExample3"> <%= form_for :user, url: users_edit_url(current_user), action: :update, method: :post do |f| %> <%= f.file_field :avatar, class: "input-group-text", onchange: "this.form.submit();" %> <% end %> </div> <br/> </div> <!-- オンラインステータス --> <a data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample"> <div style="margin-left: 20px;"> <strong> <% if current_user.status %> <span class="btn btn-success btn-sm"><i class="toggle far fa-edit"></i>オンライン online</span> <% else %> <span class="btn btn-danger btn-sm"><i class="toggle far fa-edit"></i>オフライン offline</span> <% end %> </strong> </a> <div class="collapse" id="collapseExample"> <div class="card card-body" style="width:16rem;"> <%= form_for :user, url: users_edit_url(current_user), action: :update, method: :post do |f| %> <%= f.select(:status, options_for_select([["オンライン online", true], ["オフライン offline", false]]), {}, {class: "custom-select"}) %> <br/> <br/> <%= f.submit "保存", class: "btn btn-outline-info" %> <% end %> </div> </div> </div> <br/> <!-- 自己紹介 --> <a data-toggle="collapse" href="#collapseExample2" role="button" aria-expanded="false" aria-controls="collapseExample2"> <div style="margin-left: 20px;"> <span class="btn btn-primary btn-sm"><i class="toggle far fa-edit"></i>コメント comment</span> </a> <div class="collapse" id="collapseExample2"> <div class="card card-body" style="width: 16rem;"> <%= form_for :user, url: users_edit_url(current_user), action: :update, method: :post do |f| %> <%= f.text_area :about, autofocus: true, autocomplete: 'form'%> <br/> <br/> <%= f.submit "保存", class: "btn btn-outline-info" %> <% end %> </div> </div> <div class="mx-auto" style="margin-top: 1rem; text-align: right;"> <%= l(current_user.created_at, format: :long) %> </div> </div> <!-- 電話番号 --> <div class="mx-auto" style="margin-top: 1rem; text-align: right;"> <% if !current_user.phone_number.blank? %> <span class="pull-right icon-babu" style="margin-left: 20px;"><i class="far fa-check-circle" style="color:#528fff;"></i></span> 電話番号登録済 <% else %> <span style="margin-left: 20px;">電話番号を登録していません</span> <% end %> </div> </div> </div> </div> <!-- 右側 --> <div class="col-8"> <!-- お知らせ --> <div class="card"> <div class="card-header"> お知らせ </div> <div class="card-body"> <h5 class="card-title"></h5> <p class="card-text"></p> </div> </div> <br/> <!-- 登録しているお部屋 --> <div class="card"> <div class="card-header bg-dark text-light"> 登録しているお部屋(<%= current_user.rooms.length %>) </div> <div class="card-body"> <div class="row"> <% current_user.rooms.each do |room| %> <% if room.active? %> <div class="col-6 col-md-4" style="margin-bottom: 20px;"> <%= link_to room_path(room), data: { turbolinks: false} do %> <%= image_tag room_cover(room), style: "width: 100%; height: 180;" %> <% end %> <span class="badge bg-info text-light"><%= room.listing_name %></span><br/> <span class="badge bg-secondary text-light"><%= room.address %></span><br/> <footer class="badge bg-warning" style="font-size: 0.9rem;"><%= number_to_currency(room.price) %></footer> </div> <% end %> <% end %> </div> </div> </div> </div> </div>
ブラウザ確認
http://localhost:3000/dashboard
↓↓クリックして頂けると励みになります。
| 31 |予約フォームの実装 << [ホーム] >> | 33 |レビューの実装