戻る

Rails6.0


お仕事売買サイトの構築 Rails6.0

  (0)
3,000円

タスク8-5   コメント

このタスクについて


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




注文したお仕事に対してコメント出来るようにします。


コマンド
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(3行目)
 before_action :is_authorised, only: [:show]



2.記述追加 app\controllers\orders_controller.rb(41行目)
     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(50行目)
     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> 



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

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

お仕事売買サイトの構築 Rails6.0

3,000円

フリーランスの方がお仕事を登録し、仕事を探している人が探して買うことができます。
お仕事を探している人がリクエストを出してお仕事をしてくれる人を募集する事もできます。
お仕事が売れると売上の80%が自動で指定口座に振り込まれます。
お仕事の購入はクレジットカードで決済します。
質問があればメッセージを送ることができ、リアルタイムで会話表示することができます。
検索機能、写真のアップロード、レビュー機能の実装、Facebook認証、アマゾンS3の利用方法も解説。
HEROKUへのデプロイ方法を解説。
フルコードのダウンロード可能。

タスク数: 146