[48]メッセージと会話 | リアルタイムメッセージ << [ホームに戻る] >> [50]メッセージと会話| リアルタイムコメント
注文したお仕事に対してコメント出来るようにします。
コマンド
rails g model Comment content:text user:references order:references --no-test-framework
「db\migrate\20200712092809_create_comments.rb」ファイルの記述を更新します。
記述更新 db\migrate\20200712092809_create_comments.rb
コードをコピーしてファイルの内容を置き換えて下さい。
class CreateComments < ActiveRecord::Migration[6.0] def change create_table :comments do |t| t.text :content t.references :user, foreign_key: true t.references :order, foreign_key: true, type: :uuid t.timestamps end end end
コマンド マイグレーション適用
rails db:migrate
「app\controllers\orders_controller.rb」ファイルの記述を更新します。
1.記述追加 app\controllers\orders_controller.rb(4行目)
before_action :is_authorised, only: [:show]
2.記述追加 app\controllers\orders_controller.rb(39行目)
def show @order = Order.find(params[:id]) @gig = @order.gig_id ? Gig.find(@order.gig_id) : nil @request = @order.request_id ? Request.find(@order.request_id) : nil @comments = Comment.where(order_id: params[:id]) end
3.記述追加 app\controllers\orders_controller.rb(48行目)
def is_authorised redirect_to dashboard_path, alert: "You don't have permission" unless Order.where("id = ? AND (seller_id = ? OR buyer_id = ?", params[:id], current_user.id, current_user.id) end
記述更新 app\controllers\orders_controller.rb
class OrdersController < ApplicationController before_action :authenticate_user! before_action :is_authorised, only: [:show] def create gig = Gig.find(params[:gig_id]) pricing = gig.pricings.find_by(pricing_type: params[:pricing_type]) if (pricing && !gig.has_single_pricing) || (pricing && pricing.basic? && gig.has_single_pricing) if charge(gig, pricing) return redirect_to buying_orders_path end else flash[:alert] = "価格が間違っています。" end redirect_to request.referrer end def selling_orders @orders = current_user.selling_orders end def buying_orders @orders = current_user.buying_orders end def complete @order = Order.find(params[:id]) if !@order.completed? if @order.completed! flash[:notice] = "保存しました" else flash[:notice] = "問題が発生しました" end redirect_to request.referrer end end def show @order = Order.find(params[:id]) @gig = @order.gig_id ? Gig.find(@order.gig_id) : nil @request = @order.request_id ? Request.find(@order.request_id) : nil @comments = Comment.where(order_id: params[:id]) end private def is_authorised redirect_to dashboard_path, alert: "You don't have permission" unless Order.where("id = ? AND (seller_id = ? OR buyer_id = ?", params[:id], current_user.id, current_user.id) end def charge(gig, pricing) order = gig.orders.new order.title = gig.title order.due_date = Date.today() + pricing.delivery_time.days order.seller_name = gig.user.full_name order.seller_id = gig.user.id order.buyer_name = current_user.full_name order.buyer_id = current_user.id order.amount = pricing.price * 1.1 amount = pricing.price * 1.1 host_amount = (amount * 0.8).to_i # 売上の80%がホストに入る charge = Stripe::Charge.create({ amount: (amount).to_i, customer: current_user.stripe_id, source: params[:payment], currency: "jpy", transfer_data: { amount: host_amount, destination: gig.user.merchant_id, # ホストのストライプID }, }) order.save flash[:notice] = "決済が完了しました。。" return true rescue ActiveRecord::RecordInvalid flash[:alert] = "問題が発生しました。" return false end end
「app\controllers」フォルダに「comments_controller.rb」ファイルを新規作成します。
app\controllers\comments_controller.rb(新規作成したファイル)
class CommentsController < ApplicationController before_action :authenticate_user! before_action :is_valid_order def create order = Order.find(comment_params[:order_id]) if comment_params[:content].blank? # 「無効なメッセージ」とアラートを返す return render json: {success: false} end @comment = Comment.new( user_id: current_user.id, order_id: order.id, content: comment_params[:content], ) if @comment.save redirect_to request.referrer, notice: "コメントを送りました" else redirect_to request.referrer, alert: "コメントすることができません" end end private def comment_params params.require(:comment).permit(:content, :order_id, :attachment_file) end def is_valid_order redirect_to dashboard_path, alert: "無効です" unless Order.find(comment_params[:order_id]).present? end end
ルートの設定をします。
1.記述追加 config\routes.rb(25行目)
get '/orders/:id', to: 'orders#show', as: "order_detail"
2.記述追加 config\routes.rb(32行目)
post '/comments', to: 'comments#create'
config\routes.rb
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: {omniauth_callbacks: 'omniauth_callbacks', registrations: 'registrations'} get 'pages/home' get '/dashboard', to: 'users#dashboard' get '/users/:id', to: 'users#show', as: 'users' get '/selling_orders', to: 'orders#selling_orders' get '/buying_orders', to: 'orders#buying_orders' get '/all_requests', to: 'requests#list' get '/request_offers/:id', to: 'requests#offers', as: 'request_offers' get '/my_offers', to: 'requests#my_offers' get '/search', to: 'pages#search' get 'settings/payment', to: 'users#payment', as: 'settings_payment' get 'settings/payout', to: 'users#payout', as: 'settings_payout' get '/gigs/:id/checkout/:pricing_type', to: 'gigs#checkout', as: 'checkout' get '/conversations', to: 'conversations#list', as: "conversations" get '/conversations/:id', to: 'conversations#show', as: "conversation_detail" get '/orders/:id', to: 'orders#show', as: "order_detail" post '/users/edit', to: 'users#update' post '/offers', to: 'offers#create' post '/reviews', to: 'reviews#create' post '/settings/payment', to: 'users#update_payment', as: "update_payment" post 'messages', to: 'messages#create' post '/comments', to: 'comments#create' put '/orders/:id/complete', to: 'orders#complete', as: 'complete_order' put '/offers/:id/accept', to: 'offers#accept', as: 'accept_offer' put '/offers/:id/reject', to: 'offers#reject', as: 'reject_offer' mount ActionCable.server => '/cable' resources :gigs do member do delete :delete_photo post :upload_photo end resources :orders, only: [:create] end resources :requests # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end
「app\views\orders」フォルダに「show.html.erb」ファイルを新規作成します。
app\views\orders\show.html.erb(新規作成したファイル)
<section class="section" data-channel-subscribe="order" data-order-id="<%= @order.id %>"> <div class="container"> <div class="columns"> <!-- 左側 --> <div class="column is-two-thirds"> <p class="menu-label"> 注文に対するコメント </p> <hr> <div id="comment-list"> <% @comments.each do |c| %> <%= render 'orders/comment', comment: c %> <% end %> </div> <hr> <article class="media"> <figure class="media-left"> <p class="image is-64x64"> <%= image_tag avatar_url(current_user), class: "is-rounded" %> </p> </figure> <div class="media-content"> <%= form_with model: Comment.new, id: "new-comment" do |f| %> <%= f.hidden_field :order_id, value: @order.id %> <div class="field"> <%= f.text_area :content, class: "textarea", placeholder: "コメントを入力して下さい" %> </div> <div class="field is-pulled-left"> <div class="file is-warning has-name"> <label class="file-label"> <%= f.file_field :attachment_file, class: "file-input" %> <span class="file-cta"> <span class="file-label">添付ファイル(オプション)</span> </span> <span class="file-name" id="file-name">ファイルが選択されていません</span> </label> </div> </div> <div class="field is-pulled-right"> <%= f.submit "コメントを送る", class: "button is-primary" %> </div> <% end %> </div> </article> </div> <!-- 右側 --> <div class="column"> <div class="card"> <div class="card-image"> <figure class="image is-3by2"> <%= image_tag gig_cover(@gig) if @gig %> <%= image_tag 'icon_default_image.jpg' if @request %> </figure> </div> <div class="card-content"> <p> <strong><%= @order.title %></strong> <strong class="title is-4 is-pulled-right has-text-success"><%= number_to_currency(@order.amount) %></strong> </p> <br> <small> <p>売り主: <%= @order.seller_name %></p> <br> <p>注文: <%= @order.id %></p> <br> <p><%= I18n.l(@order.created_at, format: :full_date) %></p> </small> </div> </div> </div> </div> </div> </section> <script> $(document).ready(function() { var file = $('.file-input'); file.change(function(e) { if (file[0].files.length > 0) { var attachment = file[0].files[0]; $('.file-name').text(attachment.name + " (" + attachment.size + " bytes)"); } }) }) </script>
「app\views\orders」フォルダに「_comment.html.erb」ファイルを新規作成します。
app\views\orders\_comment.html.erb(新規作成したファイル)
<article class="media"> <figure class="media-left"> <p class="image is-64x64"> <%= image_tag avatar_url(comment.user), class: "is-rounded" %> </p> </figure> <div class="media-content"> <div class="content"> <p> <strong><%= comment.user.full_name %></strong> <small class="is-pulled-right"><%= time_ago_in_words(comment.created_at) %></small> <br> <%= comment.content %> <br> </p> </div> </div> </article>
「app\views\orders\buying_orders.html.erb」ファイルの記述を更新します。
記述更新 app\views\orders\buying_orders.html.erb
11行目と32~34行目の記述を変更しています。
<section class="section"> <div class="container"> <p class="title">買った注文の確認</p> <table class="table is-fullwidth"> <thead> <tr> <th>注文日</th> <th>売り主</th> <th>タイトル</th> <th>コメント</th> <th>期日</th> <th>価格</th> <th>ステータス</th> <th>アクション</th> </tr> </thead> <tbody> <% if @orders.blank? %> <tr> <td colspan="7" class="has-text-centered"><h1>表示できる注文がありません。</h1></td> </tr> <% end %> <% @orders.each do |o| %> <tr> <td><%= I18n.l(o.created_at, format: :full_date) %></td> <td><%= o.seller_name %></td> <td> <%= link_to o.title, gig_path(o.gig) if !o.gig.nil? %> <%= link_to o.title, request_path(o.request) if !o.request.nil? %> </td> <td> <%= link_to "コメント", order_detail_path(o), data: { turbolinks: false} %> </td> <td><%= I18n.l(o.due_date) %></td> <td><%= number_to_currency(o.amount) %></td> <td> <span class="tag <%= 'is-warning' if o.inprogress? %> <%= 'is-success' if o.completed? %>"> <% if o.inprogress? %> 進行中 <% else %> お仕事完了 <% end %> </span> </td> <td> <% if !o.completed? %> <%= link_to 'お仕事完了にする', complete_order_path(o), method: :put, class: "button is-small is-primary #{'is-hidden' if o.completed?}" %> <% else %> <a class="button is-small is-outlined is-danger toggle-modal" aria-control="<%= o.id %>">レビューする</a> <div class="modal" id="<%= o.id %>"> <div class="modal-background"></div> <div class="modal-content"> <div class="box"> <%= form_for Review.new do |f| %> <%= f.hidden_field :order_id, value: o.id %> <div class="field"> <div id="star_<%= o.id %>"></div> </div> <div class="field"> <%= f.text_area :review, class: "textarea" %> </div> <a class="toggle-modal button is-light" aria-control="<%= o.id %>">キャンセル</a> <%= f.submit "レビューする", class: "button is-danger" %> <% end %> </div> </div> </div> <% end %> </td> </tr> <% end %> </tbody> </table> </div> </section> <script> $('.toggle-modal').on('click', (e) => { e.stopPropagation(); e.preventDefault(); var order_id = e.target.getAttribute('aria-control'); $('#star_' + order_id).raty({ path: '/assets/raty-js/lib/images', scoreName: 'review[stars]', score: 1 }); $('#star_' + order_id).raty('reload'); $('#' + order_id).toggleClass('is-active'); }); </script>
「app\views\orders\selling_orders.html.erb」ファイルの記述を更新します。
記述更新 app\views\orders\selling_orders.html.erb
11行目と31~33行目の記述を変更しています。
<section class="section"> <div class="container"> <p class="title">売った注文の確認</p> <table class="table is-fullwidth"> <thead> <tr> <th>注文日</th> <th>買い主</th> <th>タイトル</th> <th>コメント</th> <th>期日</th> <th>価格</th> <th>ステータス</th> </tr> </thead> <tbody> <% if @orders.blank? %> <tr> <td colspan="6" class="has-text-centered"><h1>表示できる発注はありません。</h1></td> </tr> <% end %> <% @orders.each do |o| %> <tr> <td><%= I18n.l(o.created_at, format: :full_date) %></td> <td><%= o.buyer_name %></td> <td> <%= link_to o.title, gig_path(o.gig) if !o.gig.nil? %> <%= link_to o.title, request_path(o.request) if !o.request.nil? %> </td> <td> <%= link_to "コメント", order_detail_path(o), data: { turbolinks: false} %> </td> <td><%= I18n.l(o.due_date) %></td> <td><%= number_to_currency(o.amount) %></td> <td> <span class="tag <%= 'is-warning' if o.inprogress? %> <%= 'is-success' if o.completed? %>"> <% if o.inprogress? %> 進行中 <% else %> お仕事完了 <% end %> </span> </td> </tr> <% end %> </tbody> </table> </div> </section>
ブラウザ確認
http://localhost:3000/selling_orders
http://localhost:3000/buying_orders
コメントのリンクをつけました。
お仕事の注文に対してコメントを送ることができます。
ファイル添付はまだできません。
↓↓クリックして頂けると励みになります。
[48]メッセージと会話 | リアルタイムメッセージ << [ホームに戻る] >> [50]メッセージと会話| リアルタイムコメント