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

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

Ruby on Rails6.0 | 空き部屋を登録・予約・決済できるWebサイトを作成する 91 | Bootstrap | ページネーション

[90]Bootstrap | クレジットカード決済 | Stripe(ストライプ)コネクト<< [ホームに戻る] >> [92]Bootstrap | メッセージと会話 | コントローラとビュー作成


「44 | ページネーション」の内容をBootstrapの記述に変更します。


検索ページにページング機能をつけます。


「GemFile」に以下の記述を追加します。


記述追加 GemFile(89行目)

gem 'kaminari'



GemFile

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.6'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '~> 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

# デバイス
gem 'devise'

# 日本語化
gem 'rails-i18n'

# アマゾンS3
gem "aws-sdk"

# アクションテキスト画像表示
gem "mini_magick"
gem 'image_processing', '~> 1.2'

#googleマップ
gem 'geocoder', '~> 1.4'

#facebook認証
gem 'omniauth', '= 1.9.0'
gem 'omniauth-facebook', '= 5.0.0'

#Google認証
gem 'omniauth-google-oauth2'

# 検索
gem 'ransack', '~> 2.3'

# stripe
gem 'stripe', '=4.18.1'

# stripeコネクト
gem 'omniauth-stripe-connect', '~> 2.10.0'

# ページネーション
gem 'kaminari'



コマンド(2つ)
bundle


rails g kaminari:views bootstrap4


「app\controllers\reservations_controller.rb」ファイルに以下の記述を追加します。


記述追加 app\controllers\reservations_controller.rb(40行目)

.page(params[:page]).per(5)



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 settings_payment_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).page(params[:page]).per(5)
  end

  def your_reservations
    @rooms = current_user.rooms
  end

  def approve
    @reservation.Approved!
    redirect_to your_reservations_path
  end

  def decline
    @reservation.Declined!
    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

  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!
        flash[:notice] = "お支払い手続きが完了し、ご予約されました。お越しをお待ちしております!"
      else
        reservation.Declined!
        flash[:notice] = "お支払い手続きができません。予約ができませんでした。"
      end
    end
  rescue Stripe::CardError => e
    reservation.declined!
    flash[:alert] = e.message
  end
  
end
  



「app\views\reservations\your_trips.html.erb」ファイルに以下の記述を追加します。


記述追加 app\views\reservations\your_trips.html.erb(7行目)

<%= paginate @trips %>
<br/>



app\views\reservations\your_trips.html.erb

<div class="row" style="margin-top: 50px; margin-left: 30px;">

    <div class="card">

        <h3 style="margin-top: 30px; margin-left: 30px;">ご予約内容</h3>
        <br/>
        <%= paginate @trips %>
        <br/>
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>申し込み日</th>
                    <th>ステータス</th>
                    <th>お部屋</th>
                    <th>ホスト</th>
                    <th></th>
                    <th>料金</th>
                    <th>アクション</th>
                </tr>
            </thead>
            <tbody>
                <% if @trips.blank? %>
                  <tr>
                      <td colspan="7"><h1>表示できるご予約はありません。</h1></td>
                  </tr>
                <% end %>
                <% @trips.each do |trip| %>
                    <tr>
                        <td><%= I18n.l(trip.created_at, format: :full_date) %></td>
                        <!-- ステータス -->
                        <td>
                        <% if trip.Waiting? %>
                        <p class="btn btn-outline-warning">承認待ちです。しばらくお待ち下さい。</p>
                    <% elsif trip.Approved? %>
                        <p class="btn btn-outline-success">予約済みです</p>
                    <% else  %>
                        <p class="btn btn-outline-danger">予約できませんでした</p>
                    <% end  %>                        
                        </td>
                        <td>
                            <%= link_to room_path(trip.room), data: { turbolinks: false} do %>                                
                                <%= image_tag room_cover(trip.room), style: "width: 80px;" %><br/>
                                <%= trip.room.listing_name %>
                            <% end %>
                        </td>
                        <td>
                            <%= link_to user_path(trip.room.user), class: "tootip" do %>

                                    <%= image_tag avatar_url(trip.room.user), style: "width: 80px;", class: "bd-placeholder-img figure-img img-fluid rounded-pill" %><br/>

                                <%= trip.room.user.full_name %>
                            <% end %>
                        </td>
                        <td>
                            宿泊日:<%= I18n.l(trip.start_date, format: :full_date) %><br/>
                            ご出発:<%= I18n.l(trip.end_date, format: :full_date) %>
                        </td>
                        <td><%= number_to_currency(trip.total) %></td>
                        <!-- アクション -->
                        <td>
                        <%= render partial: "reviews/guest_form", locals: {reservation: trip} if trip.Approved? %>
                        </td>
                    </tr>
                <% end %>
            </tbody>
        </table>
    </div>
</div>



ブラウザ確認
http://localhost:3000/your_trips

ページネーション
ページネーション



[90]Bootstrap | クレジットカード決済 | Stripe(ストライプ)コネクト<< [ホームに戻る] >> [92]Bootstrap | メッセージと会話 | コントローラとビュー作成