予約完了時のメール送信を宿泊者(ゲスト)が選択できるようにします。
コマンド
rails g model Setting enable_sms:boolean enable_email:boolean user:references
記述更新 db\migrate\20200701094041_create_settings.rb
コードをコピーしてファイルを置き換えて下さい。
class CreateSettings < ActiveRecord::Migration[5.0] def change create_table :settings do |t| t.boolean :enable_sms, default: true t.boolean :enable_email, default: true t.references :user, foreign_key: true t.timestamps end User.find_each do |user| Setting.create(user: user, enable_email: true, enable_sms: true) end end end
コマンド マイグレーション
rails db:migrate
記述追加 app\models\user.rb(22行目)
has_one :setting after_create :add_setting def add_setting Setting.create(user: self, enable_sms: true, enable_email: true) end
app\models\user.rb
class User < ApplicationRecord # アバター画像表示用 include Gravtastic gravtastic # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :confirmable, :omniauthable #長さ50文字以下 入力必須 validates :fullname, presence: true, length: {maximum: 50} has_many :rooms has_many :reservations has_many :guest_reviews, class_name: "GuestReview", foreign_key: "guest_id" has_many :host_reviews, class_name: "HostReview", foreign_key: "host_id" has_one :setting after_create :add_setting def add_setting Setting.create(user: self, enable_sms: true, enable_email: true) end def self.from_omniauth(auth) user = User.where(email: auth.info.email).first if user return user else where(provider: auth.provider, uid: auth.uid).first_or_create do |user| user.email = auth.info.email user.password = Devise.friendly_token[0,20] user.fullname = auth.info.name user.image = auth.info.image user.uid = auth.uid user.provider = auth.provider user.skip_confirmation! end end end def is_active_host !self.merchant_id.blank? end def generate_pin self.pin = SecureRandom.hex(2) self.phone_verified = false save end def send_pin @client = Twilio::REST::Client.new @client.messages.create( from: '+12056565281', to: self.phone_number, body: "テストサイトMinpakuです。あなたのPinコードは #{self.pin}" ) end def verify_pin(entered_pin) update(phone_verified: true) if self.pin == entered_pin end end
「app\controllers」フォルダに「settings_controller.rb」ファイルを新規作成してください。
app\controllers\settings_controller.rb(新規作成したファイル)
class SettingsController < ApplicationController def edit @setting = User.find(current_user.id).setting end def update @setting = User.find(current_user.id).setting if @setting.update(setting_params) flash[:notice] = "保存しました" else flash[:alert] = "保存できません" end render 'edit' end private def setting_params params.require(:setting).permit(:enable_sms, :enable_email) end end
記述追加 config\routes.rb
14行目に「get '/notification_settings' => 'settings#edit'」の記述追加。
17行目に「post '/notification_settings' => 'settings#update'」の記述追加。
Rails.application.routes.draw do #ルートをpages#homeに設定 root 'pages#home' get 'pages/home' get '/your_trips' => 'reservations#your_trips' get '/your_reservations' => 'reservations#your_reservations' get 'search' => 'pages#search' get 'dashboard' => 'dashboards#index' get '/host_calendar' => "calendars#host" get '/payment_method' => "users#payment" get '/payout_method' => "users#payout" get '/notification_settings' => 'settings#edit' post '/add_card' => "users#add_card" post '/notification_settings' => 'settings#update' resources :users, only: [:show] do member do post '/verify_phone_number' => 'users#verify_phone_number' patch '/update_phone_number' => 'users#update_phone_number' end end resources :rooms, except: [:edit] do member do get 'listing' get 'pricing' get 'description' get 'photo_upload' get 'amenities' get 'location' get 'preload' get 'preview' end resources :photos, only: [:create, :destroy] resources :reservations, only: [:create] resources :calendars end resources :guest_reviews, only: [:create, :destroy] resources :host_reviews, only: [:create, :destroy] resources :revenues, only: [:index] resources :reservations, only: [:approve, :decline] do member do post '/approve' => "reservations#approve" post '/decline' => "reservations#decline" end end devise_for :users, path: '', path_names: {sign_in: 'login', sign_out: 'logout', edit: 'profile', sign_up: 'registration'}, controllers: {omniauth_callbacks: 'omniauth_callbacks', registrations: 'registrations'} # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end
記述更新 app\controllers\reservations_controller.rb(91, 92行目)
send_sms(room, reservation) if reservation.user.setting.enable_sms ReservationMailer.send_email_to_guest(reservation.user, room, reservation).deliver_later if reservation.user.setting.enable_email
app\controllers\reservations_controller.rb
class ReservationsController < ApplicationController before_action :authenticate_user! before_action :set_reservation, only: [:approve, :decline] def create room = Room.find(params[:room_id]) if current_user == room.user flash[:alert] = "オーナーが予約することはできません。" elsif current_user.stripe_id.blank? flash[:alert] = "予約する前にクレジットカードを登録する必要があります。" return redirect_to payment_method_path else start_date = Date.parse(reservation_params[:start_date]) end_date = Date.parse(reservation_params[:end_date]) days = (end_date - start_date).to_i if days == 0 flash[:alert] = "宿泊日数が1泊以上でなければ予約することはできません。" else @reservation = current_user.reservations.build(reservation_params) @reservation.room = room @reservation.price = room.price @reservation.total = room.price * days #@reservation.save if @reservation.Waiting! if room.Request? flash[:notice] = "予約承認申請を送信しました。予約が承認されるまでしばらくお待ち下さい。" else charge(room, @reservation) end else flash[:alert] = "ご予約できません!" end end 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 charge(@reservation.room, @reservation) redirect_to your_reservations_path end def decline @reservation.Declined! redirect_to your_reservations_path end private def send_sms(room, reservation) @client = Twilio::REST::Client.new @client.messages.create( from: '+12056565281', to: room.user.phone_number, body: "#{reservation.user.fullname}様、#{room.listing_name}を予約しました。" ) end def charge(room, reservation) host_amount = (reservation.total * 0.8).to_i # 売上の80%がホストに入る if !reservation.user.stripe_id.blank? customer = Stripe::Customer.retrieve(reservation.user.stripe_id) charge = Stripe::Charge.create( :customer => customer.id, :amount => reservation.total, :description => room.listing_name, :currency => "jpy", transfer_data: { amount: host_amount, destination: room.user.merchant_id, # ホストのストライプID }, ) if charge reservation.Approved! send_sms(room, reservation) if reservation.user.setting.enable_sms ReservationMailer.send_email_to_guest(reservation.user, room, reservation).deliver_later if reservation.user.setting.enable_email flash[:notice] = "お支払い手続きが完了し、ご予約されました。お越しをお待ちしております!" else reservation.Declined! flash[:notice] = "お支払い手続きができません。予約ができませんでした。" end end rescue Stripe::CardError => e reservation.declined! flash[:alert] = e.message end def set_reservation @reservation = Reservation.find(params[:id]) end def reservation_params params.require(:reservation).permit(:start_date, :end_date) end end
「app\views」フォルダに「settings」フォルダを新規作成して下さい。
作成した「settings」フォルダに「edit.html.erb」ファイルを新規作成します。
app\views\settings\edit.html.erb(新規作成したファイル)
<div class="row"> <div class="col-md-3"> <ul class="sidebar-list"> <li class="sidebar-item"><%= link_to "通知設定", notification_settings_path, class: "sidebar-link active" %></li> </ul> </div> <div class="col-md-9"> <div class="panel panel-default"> <div class="panel-heading">通知設定</div> <div class="panel-body"> <div class="container"> <p>ここでは予約完了時の確認メール送信設定が行えます。</p> <br/> <%= form_for :setting do |f| %> <div class="row form-group"> <div class="col-md-6 text-center"> <%= f.check_box :enable_email %> 電子メール </div> <div class="col-md-6 text-center"> <%= f.check_box :enable_sms %> ショートメール </div> </div> <div class="text-center"> <%= f.submit "設定を保存", class: "btn btn-normal" %> </div> <% end %> </div> </div> </div> </div> </div>
ブラウザ確認
http://localhost:3000/notification_settings
宿泊者(ゲスト)が予約時の確認メールを選択できるようになりました。
ナビゲーションバーのリンクを追加します。
記述追加 app\views\shared\_navbar.html.erb
42行目と63行目にリンクの記述を追加しています。
<!-- ナビゲーションバー --> <nav class="navbar navbar-default navbar-static-top" style ="margin: 0;"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">ナビゲーション トグル</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <%= link_to "テストサイトMinpaku", root_path, class: "navbar-brand" %> </div> <div id="navbar" class="navbar-collapse collapse"> <ul class="nav navbar-nav navbar-right"> <% if (!user_signed_in?) %> <li><%= link_to "ログイン", new_user_session_path %></li> <li><%= link_to "新規ユーザ登録", new_user_registration_path %></li> <% else %> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"> <!-- アバター画像 --> <%= image_tag current_user.gravatar_url, class: "img-circle avatar-small" %> <!-- 氏名表示に変更 --> <%= current_user.fullname %> <span class="caret"></span> </a> <ul class="dropdown-menu"> <li><%= link_to "ダッシュボード", dashboard_path %></li> <li><%= link_to "登録したお部屋の管理", rooms_path %></li> <li><%= link_to "お部屋の新規登録", new_room_path %></li> <li><%= link_to "受注予約の管理(ホスト用)", your_reservations_path %></li> <li><%= link_to "予約履歴(ゲスト用)", your_trips_path %></li> <li><%= link_to "ホスト用カレンダー", host_calendar_path %></li> <li><%= link_to "収益", revenues_path %></li> <li><%= link_to "クレジットカード登録", payment_method_path, data: { turbolinks: false} %></li> <li><%= link_to "振り込み口座登録", payout_method_path %></li> <li role="separator" class="divider"></li> <li><%= link_to "ユーザ登録情報修正", edit_user_registration_path %></li> <li><%= link_to "予約メール通知設定", notification_settings_path %></li> <li><%= link_to "ログアウト", destroy_user_session_path, method: :delete %></li> </ul> </li> <% end %> </ul> </div> </div> </nav> <% if (user_signed_in?) && !current_page?(root_path) && !current_page?("/rooms/#{params[:id]}") %> <nav class="navbar navbar-default" style="background-color: #89dfd7;"> <div class="container"> <ul class="nav navbar-nav"> <li <% if current_page?(dashboard_path) %> class="active" <% end %> > <%= link_to "ダッシュボード", dashboard_path %></li> <li <% if current_page?(host_calendar_path) %> class="active" <% end %> ><%= link_to "ホスト用カレンダー", host_calendar_path %></li> <li <% if current_page?(revenues_path) %> class="active" <% end %> ><%= link_to "収益", revenues_path %></li> <li <% if current_page?(payment_method_path) %> class="active" <% end %> ><%= link_to "クレジットカード登録", payment_method_path, data: { turbolinks: false} %></li> <li <% if current_page?(payout_method_path) %> class="active" <% end %> ><%= link_to "振り込み口座登録", payout_method_path %></li> <li <% if current_page?(notification_settings_path) %> class="active" <% end %> ><%= link_to "予約メール通知設定", notification_settings_path %></li> </ul> </div> </nav> <% end %>