戻る

Rails5.0


民泊サイトの構築 Rails5.0

  (0)
2,000円

タスク4-7   レビュー

このタスクについて


タスクの内容を一部抜粋します。
プロジェクトを購入していただくとこのタスクの内容の全てを読みやすい表示で見ることができます。
プログラムコードが色分けされて見やすくなります。
プログラムコードに行番号が付きます。
本文が色分けされて見やすくなります。
そしてこのアプリケーションのフルコードをダウンロードすることが可能になります。




レビューモデルを作成します。



コマンド
1文です。
rails g model Review comment:text star:bigint room:references reservation:references guest:references host:references type


コマンド
rails g model GuestReview --parent=Review --migration=false


コマンド
rails g model HostReview --parent=Review --migration=false


記述更新 db\migrate\20200629041702_create_reviews.rb
「,default: 1」の記述追加(5行目)と「, foreign_key: { to_table: :users }」の記述追加(8,9行目)をしています。
 
class CreateReviews < ActiveRecord::Migration[5.0] 

  def change 
    create_table :reviews do |t| 
      t.text :comment 
      t.bigint :star, default: 1 
      t.references :room, foreign_key: true 
      t.references :reservation, foreign_key: true 
      t.references :guest, foreign_key: { to_table: :users } 
      t.references :host, foreign_key: { to_table: :users } 
      t.string :type 
      t.timestamps 
    end 
  end 

end 



コマンド マイグレーション
rails db:migrate


app\models\guest_review.rb
「belongs_to :guest, class_name: "User"」の追加(2行目)
 class GuestReview < Review 
    belongs_to :guest, class_name: "User" 
end 



app\models\host_review.rb
「belongs_to :host, class_name: "User"」の追加(2行目)
 class HostReview < Review 
    belongs_to :host, class_name: "User" 
end 



記述削除 app\models\review.rb
自動で記述された部分を削除します。
 class Review < ApplicationRecord 
end 



「app\models\room.rb」ファイルを編集します。


1.記述追加 app\models\room.rb(5行目)
has_many :guest_reviews



2.記述追加 app\models\room.rb(24行目)
   def average_rating 
    guest_reviews.count == 0 ? 0 : guest_reviews.average(:star).round(2).to_i 
  end  



記述追加 app\models\room.rb
 
class Room < ApplicationRecord 

  belongs_to :user 

  has_many :photos 
  has_many :reservations 
  has_many :guest_reviews 

  geocoded_by :address 

  after_validation :geocode, if: :address_changed? 

  validates :home_type, presence: true 
  validates :room_type, presence: true 
  validates :accommodate, presence: true 
  validates :bed_room, presence: true 
  validates :bath_room, presence: true 

  def cover_photo(size) 
    if self.photos.length > 0 
      self.photos[0].image.url(size) 
    else 
      "blank.jpg" 
    end 
  end 

  def average_rating 
    guest_reviews.count == 0 ? 0 : guest_reviews.average(:star).round(2).to_i 
  end  
end 



「app\models\user.rb」ファイルを編集します。


記述追加 app\models\user.rb(19,20行目)
 has_many :guest_reviews, class_name: "GuestReview", foreign_key: "guest_id" 
has_many :host_reviews, class_name: "HostReview", foreign_key: "host_id" 



記述追加 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 

  #長さ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" 
  
end 


レビューコントローラを作成します。



「app\controllers」フォルダに「「host_reviews_controller.rb」ファイルを新規作成してください。


app\controllers\host_reviews_controller.rb(新規作成したファイル)
 
class HostReviewsController < ApplicationController 

    def create 
        
      # ステップ 1: 予約が存在するかどうかを確認します(room_id、guest_id、host_id)  
      # ステップ 2: 現在のホストがこの予約のゲストをすでにレビューしているかどうかを確認します。 
  
      @reservation = Reservation.where( 
                      id: host_review_params[:reservation_id], 
                      room_id: host_review_params[:room_id], 
                      user_id: host_review_params[:guest_id] 
                     ).first 
  
      if !@reservation.nil? 
  
        @has_reviewed = HostReview.where( 
                          reservation_id: @reservation.id, 
                          guest_id: host_review_params[:guest_id] 
                        ).first 
  
        if @has_reviewed.nil? 
            # レビューを許可 
            @host_review = current_user.host_reviews.create(host_review_params) 
            flash[:success] = "レビューを作成しました。" 
        else 
            # レビュー済み 
            flash[:success] = "この予約はレビュー済みです。" 
        end 
      else 
        flash[:alert] = "予約がありません。" 
      end 
  
      redirect_back(fallback_location: request.referer) 
    end 
  
    def destroy 
      @host_review = Review.find(params[:id]) 
      @host_review.destroy 
  
      redirect_back(fallback_location: request.referer, notice: "削除しました。") 
    end 
  
    private 
      def host_review_params 
        params.require(:host_review).permit(:comment, :star, :room_id, :reservation_id, :guest_id) 
      end 
  end 



「app\controllers」フォルダに「guest_reviews_controller.rb」ファイルを新規作成して下さい。


app\controllers\guest_reviews_controller.rb(新規作成したファイル)
 
class GuestReviewsController < ApplicationController 

    def create 
      # ステップ 1: 予約が存在するかどうかを確認します(room_id、host_id、host_id) 
      # ステップ 2: 現在のホストがこの予約のゲストをすでにレビューしているかどうかを確認します。 
  
      @reservation = Reservation.where( 
                      id: guest_review_params[:reservation_id], 
                      room_id: guest_review_params[:room_id] 
                     ).first 
  
      if !@reservation.nil? && @reservation.room.user.id == guest_review_params[:host_id].to_i 
  
        @has_reviewed = GuestReview.where( 
                          reservation_id: @reservation.id, 
                          host_id: guest_review_params[:host_id] 
                        ).first 
  
        if @has_reviewed.nil? 
            # レビューを許可 
            @guest_review = current_user.guest_reviews.create(guest_review_params) 
            flash[:success] = "レビューを作成しました。" 
        else 
            # レビュー済み 
            flash[:success] = "この予約はレビュー済みです。" 
        end 
      else 
        flash[:alert] = "予約がありません。" 
      end 
  
      redirect_back(fallback_location: request.referer) 
    end 
  
    def destroy 
      @guest_review = Review.find(params[:id]) 
      @guest_review.destroy 
  
      redirect_back(fallback_location: request.referer, notice: "削除しました。") 
    end 
  
    private 
      def guest_review_params 
        params.require(:guest_review).permit(:comment, :star, :room_id, :reservation_id, :host_id) 
      end 
  end 




記述追加 app\controllers\rooms_controller.rb
「show()」メソッドに「@guest_reviews = @room.guest_reviews」の記述を追加してます。(26行目)
 
class RoomsController < ApplicationController 

  before_action :set_room, except: [:index, :new, :create] 
  before_action :authenticate_user!, except: [:show] 
  before_action :is_authorised, only: [:listing, :pricing, :description, :photo_upload, :amenities, :location, :update] 

  def index 
     @rooms = current_user.rooms 
  end 

  def new 
    @room = current_user.rooms.build 
  end 

  def create 
    @room = current_user.rooms.build(room_params) 
    if @room.save 
      redirect_to listing_room_path(@room), notice: "保存しました。" 
    else 
      flash[:alert] = "問題が発生しました。" 
      render :new 
    end 
  end 

  def show 
    @photos = @room.photos 
    @guest_reviews = @room.guest_reviews 
  end 

  def listing 
  end 

  def pricing 
  end 

  def description 
  end 

  def photo_upload 
      @photos = @room.photos 
  end 

  def amenities 
  end 

  def location 
  end 

  def update 
    new_params = room_params 
    new_params = room_params.merge(active: true) if is_ready_room 
    if @room.update(new_params) 
      flash[:notice] = "保存しました。" 
    else 
      flash[:alert] = "問題が発生しました。" 
    end 
    redirect_back(fallback_location: request.referer) 
  end 

  # 予約 開始日のAJAX 
  def preload 
    today = Date.today 
    reservations = @room.reservations.where("start_date >= ? OR end_date >= ?", today, today) 
    render json: reservations 
  end 

  # 予約 終了日のAJAX 
  def preview 
    start_date = Date.parse(params[:start_date]) 
    end_date = Date.parse(params[:end_date]) 
    output = { 
      conflict: is_conflict(start_date, end_date, @room) 
    } 
    render json: output 
  end 

  private 
    # 予約 プライベートメソッド 
    def is_conflict(start_date, end_date, room) 
      check = room.reservations.where("? < start_date AND end_date < ?", start_date, end_date) 
      check.size > 0? true : false 
    end 

    def set_room 
      @room = Room.find(params[:id]) 
    end 

    def is_authorised 
      redirect_to root_path, alert: "権限がありません。" unless current_user.id == @room.user_id 
    end 

    def is_ready_room 
      !@room.active && !@room.price.blank? && !@room.listing_name.blank? && !@room.photos.blank? && !@room.address.blank? 
    end 

    def room_params 
      params.require(:room).permit(:home_type, :room_type, :accommodate, :bed_room, :bath_room, :listing_name, :summary, :address, :is_tv, :is_kitchen, :is_air, :is_heating, :is_internet, :price, :active) 
    end 
end 



「app\controllers\users_controller.rb」ファイルを編集します。


記述追加 app\controllers\users_controller.rb(7行目)
       # ユーザーがホストの場合、ホストに対するすべてのゲストレビューを表示 
      @guest_reviews = Review.where(type: "GuestReview", host_id: @user.id) 

      # ユーザーがゲストの場合、ユーザに対するすべてのホストレビューを表示 
      @host_reviews = Review.where(type: "HostReview", guest_id: @user.id) 



記述追加 app\controllers\users_controller.rb
 
class UsersController < ApplicationController 

    def show 
      @user = User.find(params[:id]) 
      @rooms = @user.rooms 

      # ユーザーがホストの場合、ホストに対するすべてのゲストレビューを表示 
      @guest_reviews = Review.where(type: "GuestReview", host_id: @user.id) 

      # ユーザーがゲストの場合、ユーザに対するすべてのホストレビューを表示 
      @host_reviews = Review.where(type: "HostReview", guest_id: @user.id) 
     
    end 
end 


ルートを設定します。



記述追加 config\routes.rb(27,28行目)
   resources :guest_reviews, only: [:create, :destroy] 
  resources :host_reviews, only: [:create, :destroy] 



記述追加 config\routes.rb
 
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' 

  resources :users, only: [:show] 

  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] 
  end 

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

  devise_for :users, 
  path: '', 
  path_names: {sign_in: 'login', sign_out: 'logout', edit: 'profile', sign_up: 'registration'}, 
  controllers: {registrations: 'registrations'} 

  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 
end 


レビュービューを作成します。



「app\views」フォルダに「reviews」フォルダを新規作成します。
その「reviews」フォルダに「_guest_form.html.erb」ファイルを新規作成してください。



app\views\reviews\_guest_form.html.erb(新規作成したファイル)
 
<!-- buttonで Modalをトリガーします。 --> 
<button type="button" class="btn btn-normal" data-toggle="modal" data-target="#myModal_<%= reservation.id %>"> 
  レビュー 
</button> 
<!-- Modal --> 
<div id="myModal_<%= reservation.id %>" class="modal fade" role="dialog"> 
  <div class="modal-dialog"> 
    <!-- Modal の内容--> 
    <div class="modal-content"> 
      <div class="modal-header"> 
        <button type="button" class="close" data-dismiss="modal">&times;</button> 
        <h4 class="modal-title text-left">あなたのレビュー</h4> 
      </div> 
      <div class="modal-body"> 
        <%= form_for current_user.guest_reviews.new do |f| %> 
            <div class="form-group text-center"> 
              <div id="stars"></div> 
            </div> 
            <div class="form-group"> 
              <%= f.text_area :comment, rows: 3, class: "form-control" %> 
            </div> 
            <%= f.hidden_field :room_id, value: reservation.room.id %> 
            <%= f.hidden_field :reservation_id, value: reservation.id %> 
            <%= f.hidden_field :host_id, value: reservation.room.user.id %> 
            <div class="text-center"> 
              <%= f.submit "レビューを投稿", class: "btn btn-normal" %> 
            </div> 
        <% end %> 
      </div> 
    </div> 
  </div> 
</div> 



「app\views\reviews」フォルダに「_host_form.html.erb」ファイルを新規作成してください。


app\views\reviews\_host_form.html.erb(新規作成したファイル)
 
<!-- buttonで Modalをトリガーします。 --> 
<button type="button" class="btn btn-normal" data-toggle="modal" data-target="#myModal_<%= reservation.id %>"> 
  レビュー 
</button> 
<!-- Modal --> 
<div id="myModal_<%= reservation.id %>" class="modal fade" role="dialog"> 
  <div class="modal-dialog"> 
    <!-- Modal の内容--> 
    <div class="modal-content"> 
      <div class="modal-header"> 
        <button type="button" class="close" data-dismiss="modal">&times;</button> 
        <h4 class="modal-title text-left">あなたのレビュー</h4> 
      </div> 
      <div class="modal-body"> 
        <%= form_for current_user.host_reviews.new do |f| %> 
            <div class="form-group text-center"> 
              <div id="stars"></div> 
            </div> 
            <div class="form-group"> 
              <%= f.text_area :comment, rows: 3, class: "form-control" %> 
            </div> 
            <%= f.hidden_field :room_id, value: reservation.room.id %> 
            <%= f.hidden_field :reservation_id, value: reservation.id %> 
            <%= f.hidden_field :guest_id, value: reservation.user.id %> 
            <div class="text-center"> 
              <%= f.submit "レビューを投稿", class: "btn btn-normal" %> 
            </div> 
        <% end %> 
      </div> 
    </div> 
  </div> 
</div> 



記述追加 app\views\reservations\your_trips.html.erb

「<%= render partial: "reviews/guest_form", locals: {reservation: trip} %>」の記述追加(34行目)
 
<div class="row"> 
  <div class="col-md-3"> 
    <ul class="sidebar-list"> 
      <li class="sidebar-item"><%= link_to "ご予約の内容", your_trips_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"> 
        <% @trips.each do |trip| %> 
          <div class="row"> 
            <div class="col-md-3" style="white-space: nowrap"> 
              <%= I18n.l(trip.start_date, format: :full_date) %> 
            </div> 
            <div class="col-md-2"> 
              <%= link_to room_path(trip.room) do %> 
                <%= image_tag trip.room.cover_photo(:thumb) %> 
              <% end %> 
            </div> 
            <div class="col-md-5"> 
              <%= link_to trip.room.listing_name, room_path(trip.room) %><br/><br/> 
              <span> 
                <%= image_tag trip.room.user.gravatar_url, class: "img-circle avatar-small" %> 
                <%= link_to user_path(trip.room.user) do %> 
                    <%= trip.room.user.fullname %> 
                <% end %> 
              </span> 
            </div> 
            <div class="col-md-3 text-right"> 
              <%= render partial: "reviews/guest_form", locals: {reservation: trip} %> 
            </div> 
          </div> 
          <hr/> 
        <% end %> 
      </div> 
    </div> 
  </div> 
</div> 



記述追加 app\views\reservations\your_reservations.html.erb
「<%= render partial: "reviews/host_form", locals: {reservation: reservation} %>」の記述追加(38行目)
 
<div class="row"> 
  <div class="col-md-3"> 
    <ul class="sidebar-list"> 
      <li class="sidebar-item"><%= link_to "受注予約の一覧", your_reservations_path, class: "sidebar-link active" %></li> 
      <li class="sidebar-item"><%= link_to "登録したお部屋の管理", rooms_path, class: "sidebar-link" %></li> 
      <li class="sidebar-item"><%= link_to "お部屋の新規登録", new_room_path, class: "sidebar-link" %></li> 
    </ul> 
  </div> 
  <div class="col-md-9"> 
    <div class="panel panel-default"> 
      <div class="panel-heading"> 
        受注予約の一覧 
      </div> 
      <div class="panel-body"> 
        <% @rooms.each do |room| %> 
            <% room.reservations.each do |reservation| %> 
                <div class="row"> 
                  <div class="col-md-3" style="white-space: nowrap"> 
                    <%= I18n.l(reservation.start_date, format: :full_date) %> 
                  </div> 
                  <div class="col-md-2"> 
                    <%= link_to room_path(reservation.room) do %> 
                        <%= image_tag reservation.room.cover_photo(:thumb) %> 
                    <% end %> 
                  </div> 
                  <div class="col-md-5"> 
                    <%= link_to reservation.room.listing_name, room_path(reservation.room) %><br/><br/> 
                    <span> 
                      <%= link_to user_path(reservation.user) do %> 
                        <%= image_tag reservation.user.gravatar_url, class: "img-circle avatar-small" %>&nbsp; 
                        <%= reservation.user.fullname %> 
                      <% end %> 
                    </span> 
                  </div> 
                  <div class="col-md-3 text-right"> 
                    <%= render partial: "reviews/host_form", locals: {reservation: reservation} %> 
                  </div> 
                </div> 
                <hr/> 
            <% end %> 
        <% end %> 
      </div> 
    </div> 
  </div> 
</div> 



「app\views\reviews」フォルダに「_guest_list.html.erb」ファイルを新規作成します。


app\views\reviews\_guest_list.html.erb(新規作成したファイル)
 
<% if @guest_reviews.count == 0 %> 
  <div class="text-center"> 
    <h4>レビューはありません。</h4> 
  </div> 
<% else %> 
  <% @guest_reviews.order(id: :desc).each do |r| %> 
    <hr/> 
    <div class="row"> 
      <div class="col-md-3 text-center"> 
        <%= image_tag r.guest.gravatar_url, class: "img-circle avatar-medium" %><br/><br/> 
        <strong><%= r.guest.fullname %></strong> 
      </div> 
      <div class="col-md-9"> 
        <div <%= r.star %>"></div> 
          <% if current_user && current_user == r.guest %> 
          <span class="pull-right"> 
          <%= link_to r, method: :delete, data: {confirm: "本当にいいですか?"} do %> 
            <i class="fa fa-trash-o fa-lg"></i> 
          <% end %> 
        </span> 
        <% end %> 
      </div> 
      <div><%= r.created_at.strftime('%Y年%-m月%-d日 %-H時%-M分') %></div> 
      <div><%= r.comment %></div> 
    </div> 
  <% end %> 
<% end %> 



「app\views\reviews」フォルダに「_host_list.html.erb」ファイルを新規作成します。


app\views\reviews\_host_list.html.erb(新規作成したファイル)
 
<% if @host_reviews.count == 0 %> 
  <div class="text-center"> 
    <h4>レビューはありません。</h4> 
  </div> 
<% else %> 
  <% @host_reviews.order(id: :desc).each do |r| %> 
    <hr/> 
    <div class="row"> 
      <div class="col-md-3 text-center"> 
        <%= image_tag r.host.gravatar_url, class: "img-circle avatar-medium" %><br/><br/> 
        <strong><%= r.host.fullname %></strong> 
      </div> 
      <div class="col-md-9"> 
        <div <%= r.star %>"></div> 
          <% if current_user && current_user == r.host %> 
          <span class="pull-right"> 
          <%= link_to r, method: :delete, data: {confirm: "本当にいいですか?"} do %> 
            <i class="fa fa-trash-o fa-lg"></i> 
          <% end %> 
        </span> 
        <% end %> 
      </div> 
      <div><%= r.created_at.strftime('%Y年%-m月%-d日 %-H時%-M分') %></div> 
      <div><%= r.comment %></div> 
    </div> 
  <% end %> 
<% end %> 



記述追加 app\views\rooms\show.html.erb(126行目)
 
    <!-- レビュー --> 
    <div class="row"> 
      <div class="col-md-12"> 
        <h3> 
          <%= pluralize(@guest_reviews.count, "Review") %> 
          <span id="average_rating"></span> 
        </h3> 
        <div class="container"> 
          <div><%= render "reviews/guest_list" %></div> 
        </div> 
      </div> 
    </div> 
    <br/> 
    <hr/> 



app\views\rooms\show.html.erb
 
<!-- 写真 --> 
<div class="row"> 
  <div class="col-md-12"> 
    <%= image_tag @room.cover_photo(nil), width: "100%" %> 
  </div> 
</div> 
<br/> 
<div class="row"> 
  <!-- 左パネル --> 
  <div class="col-md-8"> 
    <!-- お部屋の名前 --> 
    <div class="row"> 
      <div class="col-md-8"> 
        <h1><%= @room.listing_name %></h1> 
        <%= @room.address %> 
      </div> 
      <div class="col-md-4 text-center"> 
        <%= image_tag @room.user.gravatar_url, class: "img-circle avatar-large" %><br/><br/> 
        <%= @room.user.fullname %> 
      </div> 
    </div> 
    <hr/> 
    <!-- 部屋のインフォメーション --> 
    <div class="row text-babu"> 
      <div class="row text-center row-space-1"> 
        <div class="col-md-3"> 
          <i class="fa fa-home fa-2x"></i> 
        </div> 
        <div class="col-md-3"> 
          <i class="fa fa-user-circle-o fa-2x"></i> 
        </div> 
        <div class="col-md-3"> 
          <i class="fa fa-bed fa-2x"></i> 
        </div> 
        <div class="col-md-3"> 
          <i class="fa fa-bath fa-2x"></i> 
        </div> 
      </div> 
      <div class="row text-center"> 
        <div class="col-md-3"><%= @room.home_type %></div> 
        <div class="col-md-3"><%= pluralize(@room.accommodate, "人宿泊可能") %></div> 
        <div class="col-md-3"><%= pluralize(@room.bed_room, "台") %></div> 
        <div class="col-md-3"><%= pluralize(@room.bath_room, "部屋") %></div> 
      </div> 
    </div> 
    <hr/> 
    <!-- 詳細 --> 
    <div class="row"> 
      <div class="col-md-12"> 
        <h3>お部屋の詳細</h3> 
        <p><%= @room.summary %></p> 
      </div> 
    </div> 
    <hr/> 
    <!-- アメニティ --> 
    <div class="row"> 
      <div class="col-md-3"> 
        <h4>アメニティ</h4> 
      </div> 
      <div class="col-md-9"> 
        <div class="row"> 
          <div class="col-md-6"> 
            <ul class="amenities"> 
              <li class="<%= 'text-line-through' if !@room.is_tv %>">テレビ</li> 
              <li class="<%= 'text-line-through' if !@room.is_kitchen %>">キッチン</li> 
              <li class="<%= 'text-line-through' if !@room.is_internet %>">インターネット</li> 
            </ul> 
          </div> 
          <div class="col-md-6"> 
            <ul class="amenities"> 
              <li class="<%= 'text-line-through' if !@room.is_heating %>">暖房</li> 
              <li class="<%= 'text-line-through' if !@room.is_air %>">エアコン</li> 
            </ul> 
          </div> 
        </div> 
      </div> 
    </div> 
    <hr/> 
    <!-- カルーセル表示 --> 
    <div class="row"> 
      <% if @photos.length > 0 %> 
          <div id="myCarousel" class="carousel slide" data-ride="carousel"> 
          <!-- 表示 --> 
          <ol class="carousel-indicators"> 
            <% @photos.each do |photo| %> 
                <li data-target="#myCarousel" data-slide-to="<%= photo.id %>"></li> 
            <% end %> 
          </ol> 
          <!-- スライド --> 
          <div class="carousel-inner"> 
            <% @photos.each do |photo| %> 
                <div class="item <%= 'active' if photo.id == @photos[0].id %>"> 
                  <%= image_tag photo.image.url() %> 
                </div> 
            <% end %> 
          </div> 
          <!-- 左右移動 --> 
          <a class="left carousel-control" href="#myCarousel" data-slide="prev"> 
            <span class="glyphicon glyphicon-chevron-left"></span> 
            <span class="sr-only">戻る</span> 
          </a> 
          <a class="right carousel-control" href="#myCarousel" data-slide="next"> 
            <span class="glyphicon glyphicon-chevron-right"></span> 
            <span class="sr-only">次へ</span> 
          </a> 
        </div> 
      <% end %> 
    </div> 
    <hr/> 
    <!-- レビュー --> 
    <div class="row"> 
      <div class="col-md-12"> 
        <h3> 
          <%= pluralize(@guest_reviews.count, "Review") %> 
          <span id="average_rating"></span> 
        </h3> 
        <div class="container"> 
          <div><%= render "reviews/guest_list" %></div> 
        </div> 
      </div> 
    </div> 
    <br/> 
    <hr/> 
    <!-- GOOGLE マップ --> 
    <div class="row"> 
      <div id="map" style="width: 100%; height: 400px"></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_photo(:medium) %></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=AIzaSyBojDcZmScBkIOISjoYREjgid99iZUL2Tk&callback=initMap" type="text/javascript"></script> 
    </div> 
    <hr/> 
    <!-- 近くのお部屋を検索 --> 
    <div class="row"> 
      <h3>お近くのお部屋</h3> 
      <% for room in @room.nearbys(10) %> 
          <div class="col-md-4"> 
            <div class="panel panel-default"> 
              <div class="panel-heading preview"> 
                <%= image_tag room.cover_photo(:medium) %> 
              </div> 
              <div class="panel-body"> 
                <%= link_to room.listing_name, room %><br/> 
                (距離:<%= room.distance.round(2) %> Km) 
              </div> 
            </div> 
          </div> 
      <% end %> 
    </div> 
  </div> 
  <!-- 右パネル --> 
  <div class="col-md-4"> 
    <!-- 予約フォーム --> 
    <%= render 'reservations/form' %> 
  </div> 
</div> 



記述追加 app\views\users\show.html.erb(45行目)
 
    <br/> 
    <h4>ゲストからのレビュー (<%= @guest_reviews.count %>)</h4> 
    <div class="row"> 
      <%= render "reviews/guest_list" %> 
    </div> 
    <br/> 
    <h4>ホストからのレビュー (<%= @host_reviews.count %>)</h4> 
    <div class="row"> 
      <%= render "reviews/host_list" %> 
    </div> 




この続きはプロジェクトを購入していただくことで見ることができます。
プロジェクトを購入していただくとこのタスクの内容の全てを読みやすい表示で見ることができます。
プログラムコードが色分けされて見やすくなります。
プログラムコードに行番号が付きます。
本文が色分けされて見やすくなります。
そしてプロジェクトを購入するとこのアプリケーションのフルコードをダウンロードすることができます。

まだレビューはありません。

民泊サイトの構築 Rails5.0

2,000円

民泊サイトを構築します。
ホストは部屋を登録し、ゲストは宿泊予約できます。
ゲストはクレジットカードで支払いをし、ホストには料金の80%が自動で口座に振り込まれます。
Googleマップによる表示、AJAX検索、日付カレンダーによる予約、フルカレンダーによる部屋管理ができます。
リアルタイムメッセージにより連絡がとれます。
予約確認メールの送信も可能。
写真のアップロード機能、アマゾンS3の利用方法も解説。
レビュー機能の実装、電話番号認証の実装方法解説。
HEROKUへのデプロイ方法を解説。
フルコードのダウンロード可能。

タスク数: 136