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

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

Rails7.1 | 民泊予約アプリ作成 | 34 | 予約ステータス

↓↓クリックして頂けると励みになります。



33 | Ransack】 << 【ホーム】 >> 【35 | Full Calendar


予約のステータスを実装し、受注した予約を完了させる処理をさせます。
Reservationモデルにstatusカラムを追加します。
コマンド
rails g migration AddStatusToReservations status:bigint


記述追加 db\migrate\20200728030757_add_status_to_reservations.rb
3行目に「, default: 0」の記述追加

class AddStatusToReservations < ActiveRecord::Migration[7.1]
  def change
    add_column :reservations, :status, :bigint, default: 0
  end
end



コマンド
rails db:migrate


モデルにステータスの詳細を定義します。
記述追加 app\models\reservation.rb(3行目)

   # status: {待ち: 0, 済み: 1}
   enum status: {Waiting: 0, Approved: 1}



app\models\reservation.rb

class Reservation < ApplicationRecord

  # status: {待ち: 0, 済み: 1}
  enum status: {Waiting: 0, Approved: 1}

  belongs_to :user
  belongs_to :room

  has_many :reviews

end



「app\controllers\reservations_controller.rb」ファイルを編集していきます。


1.4行目に以下の記述を追加します。

before_action :set_reservation, only: [:approve]



2.36行目から「approve()」メソッド追加。

    def approve
      @reservation.Approved!
      redirect_to your_reservations_path
    end



3.46行目にプライベートメソッド「set_reservation()」を追加しています。

    def set_reservation
      @reservation = Reservation.find(params[:id])
    end



app\controllers\reservations_controller.rb

class ReservationsController < ApplicationController
    
  before_action :authenticate_user!
  before_action :set_reservation, only: [:approve]

  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

  def approve
    @reservation.Approved!
    flash[:notice] = "ステータスを完了にしました。"
    redirect_to your_reservations_path
  end    

  private
  def reservation_params
      params.require(:reservation).permit(:start_date, :end_date)
  end
  
  def set_reservation
    @reservation = Reservation.find(params[:id])
  end

end



ルートを設定します。
記述追加 config\routes.rb(34行目)

  resources :reservations, only: [:approve, :decline] do
    member do
      post '/approve', to: "reservations#approve"
    end
  end



config\routes.rb

Rails.application.routes.draw do

  # ルートを app\views\pages\home.html.erb に設定
  root 'pages#home'

  # get
  get 'pages/home'
  get '/dashboard', to: 'users#dashboard'
  get '/users/:id', to: 'users#show', as: 'user'
  get '/your_trips', to: 'reservations#your_trips'
  get '/your_reservations', to: 'reservations#your_reservations'
  get 'search', to: 'pages#search'

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

  resources :reservations, only: [:approve] do
    member do
      post '/approve', to: "reservations#approve"
    end
  end

  resources :guest_reviews, only: [:create, :destroy]
  resources :host_reviews, only: [:create, :destroy]

  # device
  devise_for :users, 
  path: '', 
  path_names: {sign_up: 'register', sign_in: 'login', edit: 'profile', sign_out: 'logout'},
  controllers: {omniauth_callbacks: 'omniauth_callbacks', registrations: 'registrations'}

  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
  # Can be used by load balancers and uptime monitors to verify that the app is live.
  get "up" => "rails/health#show", as: :rails_health_check

  # Defines the root path route ("/")
  # root "posts#index"
end



「app\views\reservations\your_reservations.html.erb」ファイルを編集していきます。


app\views\reservations\your_reservations.html.erb

<div class="container mt-4">
    <div class="card">
        <div class="card-body">

            <h5 class="card-title text-danger h3 font1">予約内容(ホスト)</h5>
            <% if @rooms.blank? %>
                <h5 class="font1">表示できる予約はありません。</h5>
            <% end %>
            
            <% @rooms.each do |room| %>
                <% room.reservations.each do |reservation| %>
                    <% if reservation.Waiting? then %>
                        <div class="card mt-4">
                            <div class="card-body">
                                <div class="mt-2">
                                    <span class="font1 alert alert-success text-center">受注</span>
                                    <% if reservation.end_date < Date.today %>
                                        <% if reservation.Waiting? %>
                                            <%= link_to approve_reservation_path(reservation), data: { turbo_method: :post, turbo_confirm: '完了にしてよろしいですか?' } do %>
                                                <i class="fa fa-thumbs-up fa-lg" style="color: green;"></i><span class="badge bg-success">完了</span>
                                            <% end %>
                                    
                                        <% end  %>
                                    <% end %> 
                                </div>
                                <ul class="list-group mt-4">

                                    <li class="list-group-item" style="border: none;">
                                        <span class="font1">申込日:</span><%= I18n.l(reservation.created_at, format: :full_date) %>
                                    </li>
                                    <li class="list-group-item" style="border: none;">
                                    <span class="font1">部屋名:</span>
                                        <%= link_to room_path(reservation.room), style: "text-decoration: none;", data: { turbo: false} do %>                                
                                            <span class="btn btn-light"><%= reservation.room.listing_name %></span>
                                        <% end %>                            
                                    </li>
                                    <li class="list-group-item" style="border: none;">
                                    <span class="font1">ゲスト:</span>
                                        <%= link_to user_path(reservation.room.user), class: "tootip", style: "text-decoration: none;" do %>
                                                <span class="btn btn-light"><%= reservation.user.full_name %></span>
                                        <% end %>
                                    </li>
                                    <li class="list-group-item" style="border: none;">
                                    <span class="font1">宿泊日:</span>   <%= I18n.l(reservation.start_date, format: :full_date) %>                     
                                    </li>
                                    <li class="list-group-item" style="border: none;">
                                    <span class="font1">ご出発:</span>   <%= I18n.l(reservation.end_date, format: :full_date) %>                       
                                    </li>
                                    <li class="list-group-item" style="border: none;">
                                        <span class="font1">泊数:</span><%=reservation.total/reservation.price %></li>
                                    <li class="list-group-item" style="border: none;">
                                        <span class="font1">料金:</span><%= number_to_currency(reservation.total) %>
                                    </li>
                                    <li class="list-group-item mt-4" style="border: none;">
                                        <% if reservation.end_date < Date.today %>
                                            <!-- レビュー -->
                                            <%= render partial: "reviews/host_form", locals: {reservation: reservation} %>
                                        <% else %>
                                            <span class="alert alert-danger" style="font-size: 0.7rem;">チェックアウト後にレビューできます</span>
                                        <% end %>
                                    </li>                            
                                </ul>

                            </div>
                        </div>
 
                    <% end %>
                <% end %>
            <% end %>

            <% @rooms.each do |room| %>
                <% room.reservations.each do |reservation| %>
                    <% if reservation.Approved? then %>
                        <div class="card mt-4">
                            <div class="card-body">
                                <div class="mt-2">
                                    <span class="font1 alert alert-secondary text-center">完了</span>
                                    <% if reservation.end_date < Date.today %>
                                        <% if reservation.Waiting? %>
                                            <%= link_to approve_reservation_path(reservation), data: { turbo_method: :post, turbo_confirm: '完了にしてよろしいですか?' } do %>
                                                <i class="fa fa-thumbs-up fa-lg" style="color: green;"></i><span class="badge bg-success">完了</span>
                                            <% end %>
                                    
                                        <% end  %>
                                    <% end %> 
                                </div>
                                <ul class="list-group mt-4">

                                    <li class="list-group-item" style="border: none;">
                                        <span class="font1">申込日:</span><%= I18n.l(reservation.created_at, format: :full_date) %>
                                    </li>
                                    <li class="list-group-item" style="border: none;">
                                    <span class="font1">部屋名:</span>
                                        <%= link_to room_path(reservation.room), style: "text-decoration: none;", data: { turbo: false} do %>                                
                                            <span class="btn btn-light"><%= reservation.room.listing_name %></span>
                                        <% end %>                            
                                    </li>
                                    <li class="list-group-item" style="border: none;">
                                    <span class="font1">ゲスト:</span>
                                        <%= link_to user_path(reservation.room.user), class: "tootip", style: "text-decoration: none;" do %>
                                                <span class="btn btn-light"><%= reservation.user.full_name %></span>
                                        <% end %>
                                    </li>
                                    <li class="list-group-item" style="border: none;">
                                    <span class="font1">宿泊日:</span>   <%= I18n.l(reservation.start_date, format: :full_date) %>                     
                                    </li>
                                    <li class="list-group-item" style="border: none;">
                                    <span class="font1">ご出発:</span>   <%= I18n.l(reservation.end_date, format: :full_date) %>                       
                                    </li>
                                    <li class="list-group-item" style="border: none;">
                                        <span class="font1">泊数:</span><%=reservation.total/reservation.price %></li>
                                    <li class="list-group-item" style="border: none;">
                                        <span class="font1">料金:</span><%= number_to_currency(reservation.total) %>
                                    </li>
                                    <li class="list-group-item mt-4" style="border: none;">
                                        <% if reservation.end_date < Date.today %>
                                            <!-- レビュー -->
                                            <%= render partial: "reviews/host_form", locals: {reservation: reservation} %>
                                        <% else %>
                                            <span class="alert alert-danger" style="font-size: 0.7rem;">チェックアウト後にレビューできます</span>
                                        <% end %>
                                    </li>                            
                                </ul>

                            </div>
                        </div>
 
                    <% end %>
                <% end %>
            <% end %>

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



動作を確認します。
ブラウザ確認
http://localhost:3000/your_reservations


チェックアウトの日付を過ぎると「レビュー」ボタンと「完了」ボタンが表示されます。
完了ボタンを押すと受注完了となります。

PCレイアウト
PCレイアウト


モバイルレイアウト
モバイルレイアウト



完了ボタンを押すと、ステータスが完了になります。

ステータス完了
ステータス完了



33 | Ransack】 << 【ホーム】 >> 【35 | Full Calendar




↓↓クリックして頂けると励みになります。