戻る

Rails6.0


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

  (0)
3,000円

タスク4-8   レビュー

このタスクについて


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




「raty-js」をインストールします。


コマンド
yarn add raty-js


「app\assets\stylesheets\application.scss」ファイルに以下の記述を追加します。


記述追加 app\assets\stylesheets\application.scss(27行目)
@import 'raty-js/lib/jquery.raty';



app\assets\stylesheets\application.scss
 
/* 
 * This is a manifest file that'll be compiled into application.css, which will include all the files 
 * listed below. 
 * 
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's 
 * vendor/assets/stylesheets directory can be referenced here using a relative path. 
 * 
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the 
 * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS 
 * files in this directory. Styles in this file should be added after the last require_* statement. 
 * It is generally better to create a new file per style scope. 
 * 
 *= require_tree . 
 *= require_self 
 */ 
 
 @import 'bulma'; 
 @import 'bulma-extensions'; 
 @import 'bulma-extensions/bulma-carousel/dist/css/bulma-carousel.min'; 
 @import 'noty/lib/noty'; 
 @import 'noty/lib/themes/sunset'; 
 @import 'dropzone/dist/basic.css'; 
 @import 'dropzone/dist/dropzone.css'; 
 @import 'raty-js/lib/jquery.raty'; 



「app\javascript\packs\application.js」ファイルに以下の記述を追加します。


記述追加 app\javascript\packs\application.js(10行目)
require("raty-js")



app\javascript\packs\application.js
 
// This file is automatically compiled by Webpack, along with any other files 
// present in this directory. You're encouraged to place your actual application logic in 
// a relevant structure within app/javascript and only use these pack files to reference 
// that code so it'll be compiled. 

require("@rails/ujs").start() 
require("turbolinks").start() 
require("@rails/activestorage").start() 
require("channels") 
require("raty-js") 

window.Noty = require("noty") 
window.Dropzone = require("dropzone") 
window.BulmaCarousel = require("bulma-extensions/bulma-carousel/dist/js/bulma-carousel") 

$(document).on('turbolinks:load', () => { 
    $('.toggle').on('click', (e) => { 
        e.stopPropagation(); 
        e.preventDefault(); 
        $('#' + e.target.getAttribute('aria-controls')).toggleClass('is-hidden'); 
    }) 
}) 

// Uncomment to copy all static images under ../images to the output folder and reference 
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>) 
// or the `imagePath` JavaScript helper below. 
// 
// const images = require.context('../images', true) 
// const imagePath = (name) => images(name, true) 

require("trix") 
require("@rails/actiontext") 



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


コマンド
一文です。
rails g model Review review:text stars:bigint order:references gig:references buyer:references seller:references --no-test-framework


「db\migrate\20200710011458_create_reviews.rb」ファイルを以下のように更新します。


記述更新 db\migrate\20200710011458_create_reviews.rb
コードをコピーしてファイルの内容を置き換えて下さい。
 
class CreateReviews < ActiveRecord::Migration[6.0] 
  def change 
    create_table :reviews do |t| 
      t.text :review 
      t.integer :stars, default: 1 
      t.references :order, null: false, foreign_key: true, type: :uuid 
      t.references :gig, null: true, foreign_key: true 
      t.references :buyer, foreign_key: { to_table: :users } 
      t.references :seller, foreign_key: { to_table: :users } 
      t.timestamps 
    end 
  end 
end 



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


「app\models\review.rb」ファイルを以下のように編集します。


記述編集 app\models\review.rb
 class Review < ApplicationRecord 
  belongs_to :order 
  belongs_to :gig, required: false 
  belongs_to :buyer, class_name: "User" 
  belongs_to :seller, class_name: "User" 
end 



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


記述追加 app\models\order.rb(8行目)
has_many :reviews



app\models\order.rb
 class Order < ApplicationRecord 
  belongs_to :gig, required: false 
  belongs_to :request, required: false 
  belongs_to :buyer, class_name: "User" 
  belongs_to :seller, class_name: "User" 
  has_many :reviews 
  enum status: [:inprogress, :completed] 
end 



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


1.記述追加 app\models\gig.rb(7行目)
has_many :reviews



2.記述追加 app\models\gig.rb(16行目)
   def average_rating 
    reviews.count == 0 ? 0 : reviews.average(:stars).round(1) 
  end 



app\models\gig.rb
 
class Gig < ApplicationRecord 

  belongs_to :user 
  belongs_to :category 

  has_many :pricings 
  has_many :orders 
  has_many :reviews 
  has_many_attached :photos 

  has_rich_text :description 

  accepts_nested_attributes_for :pricings 

  validates :title, presence: { message: '空白にはできません' } 

  def average_rating 
    reviews.count == 0 ? 0 : reviews.average(:stars).round(1) 
  end 
  
end 



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


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

    def create 
        order = Order.find(review_params[:order_id]) 
        if order && current_user.id == order.buyer.id 
            if Review.exists?(order_id: review_params[:order_id], buyer_id: current_user.id) 
                flash[:alert] = "レビュー済みです。" 
            else 
                review = Review.new(review_params) 
                review.gig = order.gig 
                review.buyer = current_user 
                review.seller = order.seller 
                if review.save 
                    flash[:notice] = "レビューを投稿しました。" 
                else 
                    flash[:alert] = "レビューできません" 
                end 
            end 
        else 
            flash[:alert] = "無効です" 
        end 
        redirect_to request.referrer 
    end 

    private 
    def review_params 
        params.require(:review).permit(:stars, :review, :order_id) 
    end 
end 



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


記述追加 app\controllers\users_controller.rb(9行目)
@reviews = Review.where(seller_id: params[:id]).order("created_at desc")



app\controllers\users_controller.rb
 
class UsersController < ApplicationController 

  before_action :authenticate_user! 

  def dashboard 
  end 

  def show 
    @user = User.find(params[:id]) 
    @reviews = Review.where(seller_id: params[:id]).order("created_at desc") 
  end 

  def update 
    @user = current_user 
    if @user.update_attributes(current_user_params) 
      flash[:notice] = "保存しました" 
    else 
      flash[:alert] = "更新できません" 
    end 
    redirect_to dashboard_path 
  end 

  private 
  def current_user_params 
    params.require(:user).permit(:from, :about, :status, :language, :avatar) 
  end 
end 



ルートの設定をします。


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


記述追加 config\routes.rb(22行目)
 post '/reviews', to: 'reviews#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' 
  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' 

  post '/users/edit', to: 'users#update' 
  post '/offers', to: 'offers#create' 
  post '/reviews', to: 'reviews#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' 

  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\buying_orders.html.erb」ファイルに以下の記述を追加します。


1.記述追加 app\views\orders\buying_orders.html.erb(42行目)
 
<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> 



2.記述追加 app\views\orders\buying_orders.html.erb(77行目)
 
<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\buying_orders.html.erb
コードをコピーしてファイルの内容を置き換えて下さい。
 
<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="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><%= 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> 



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


ステータスが「お仕事完了」になると「レビューする」ボタンが表示されます。


「レビューする」ボタン




レビューを投稿して確認します。


レビューを投稿




ダッシュボードを修正します。


記述追加 app\views\users\dashboard.html.erb(214行目)          
 <span class="star-review"><i class="fa fa-star"></i> 
    <%= gig.average_rating %> 
    <span class="has-text-primary">(<%= gig.reviews.count %>)</span> 
</span>   


app\views\users\dashboard.html.erb
 
<section class="section"> 
    <div class="container"> 
        <div class="columns"> 
        
            <!-- 左パネル --> 
            <div class="column is-one-third"> 
                <div class="columns is-multiline"> 
                    <!-- 上部 --> 
                    <div class="column is-full"> 
                        <div class="card"> 
                            <!-- アバター --> 
                            <div class="card-content is-horizontal-center is-flex"> 
                                <figure class="image is-256x256"> 
                                    <%= image_tag avatar_url(current_user), class: "is-rounded" %> 
                                </figure> 
                            </div> 
                            
                            <div class="card-content"> 
                                <!-- 画像アップロードボタン --> 
                                <div class="content has-text-centered"> 
                                    <p class="title is-5"> 
                                        <%= current_user.full_name %> 
                                    </p> 
                                    <%= form_for :user, url: users_edit_url(@user), action: :update, method: :post do |f| %> 
                                        <div class="file"> 
                                            <label class="button is-primary is-outlined is-fullwidth"> 
                                                <%= f.file_field :avatar, class: "file-input", onchange: "this.form.submit();" %> 
                                                <i class="fas fa-upload"></i>&nbsp;&nbsp;&nbsp; アバター画像アップロード 
                                            </label> 
                                        </div> 
                                    <% end %>                               
                                </div> 
                                <hr class="h-10"> 
                                
                                <!-- アカウント情報 --> 
                                <article class="media"> 
                                    <div class="media-content">アカウント登録日</div> 
                                    <div class="media-right"> 
                                        <strong><%= I18n.l(current_user.created_at, format: :full_date) %></strong> 
                                    </div> 
                                </article> 
                                <hr class="h-10"> 
                                
                                <!-- 出身地 --> 
                                <article> 
                                    <div class="media"> 
                                        <div class="media-content">出身地</div> 
                                        <div class="media-right"> 
                                            <strong><%= current_user.from %></strong> <i class="toggle far fa-edit" aria-controls="user-from"></i> 
                                        </div> 
                                    </div> 
                                    <div class="content"> 
                                        <%= form_for :user, url: users_edit_url(@user), action: :update, method: :post, html: {id: 'user-from', class: 'is-hidden'} do |f| %> 
                                            <div class="field"> 
                                                <%= f.text_field :from, autofocus: true, autocomplete: 'form', class: 'input'%> 
                                            </div> 
                                            <a class="toggle button is-light" aria-controls="user-from">キャンセル</a> 
                                            <%= f.submit "保存", class: "button is-danger" %> 
                                        <% end %> 
                                    </div> 
                                </article>                                
                                <hr class="h-10"> 
                                <!-- オンラインステータス --> 
                                <article> 
                                    <div class="media"> 
                                        <div class="media-content">ステータス</div> 
                                        <div class="media-right"> 
                                            <strong><% if current_user.status %> オンライン <% else %> オフライン <% end %></strong> <i class="toggle far fa-edit" aria-controls="user-status"></i> 
                                        </div> 
                                    </div> 
                                    <div class="content"> 
                                        <%= form_for :user, url: users_edit_url(@user), action: :update, method: :post, html: {id: 'user-status', class: 'is-hidden'} do |f| %> 
                                            <div class="field"> 
                                                <%= f.select(:status, options_for_select([["オンライン", true], ["オフライン", false]]), {}, {class: "select is-fullwidth"}) %> 
                                            </div> 
                                            <a class="toggle button is-light" aria-controls="user-status">キャンセル</a> 
                                            <%= f.submit "保存", class: "button is-danger" %> 
                                        <% end %> 
                                    </div> 
                                </article> 
                            </div> 
                        </div> 
                    </div> 
                    <!-- 下部 --> 
                    <div class="column is-full"> 
                        <div class="card"> 
                            <div class="card-content"> 
                                <!-- アカウント詳細 --> 
                                <article> 
                                    <div class="media"> 
                                        <div class="media-content"> 
                                            <p> 
                                                <strong>自己紹介</strong> 
                                                <br> 
                                                <%= current_user.about %> 
                                            </p> 
                                        </div> 
                                        <div class="media-right"> 
                                            <i class="toggle far fa-edit" aria-controls="user-about"></i> 
                                        </div> 
                                    </div> 
                                    <div class="content"> 
                                        <%= form_for :user, url: users_edit_url(@user), action: :update, method: :post, html: {id: 'user-about', class: 'is-hidden'} do |f| %> 
                                            <div class="field"> 
                                                <%= f.text_area :about, autofocus: true, autocomplete: 'form', class: 'input'%> 
                                            </div> 
                                            <a class="toggle button is-light" aria-controls="user-about">キャンセル</a> 
                                            <%= f.submit "保存", class: "button is-danger" %> 
                                        <% end %> 
                                    </div> 
                                </article> 
                                <hr class="h-10"> 
                                <!-- 言語 --> 
                                <article> 
                                    <div class="media"> 
                                        <div class="media-content"> 
                                            <p> 
                                                <strong>言語</strong> 
                                                <br> 
                                                <%= current_user.language %> 
                                            </p> 
                                        </div> 
                                        <div class="media-right"> 
                                            <i class="toggle far fa-edit" aria-controls="user-language"></i> 
                                        </div> 
                                    </div> 
                                    <div class="content"> 
                                        <%= form_for :user, url: users_edit_url(@user), action: :update, method: :post, html: {id: 'user-language', class: 'is-hidden'} do |f| %> 
                                            <div class="field"> 
                                                <%= f.text_field :language, autofocus: true, autocomplete: 'form', class: 'input'%> 
                                            </div> 
                                            <a class="toggle button is-light" aria-controls="user-language">キャンセル</a> 
                                            <%= f.submit "保存", class: "button is-danger" %> 
                                        <% end %> 
                                    </div> 
                                </article> 
                                <hr class="h-10"> 
                                
                                <!-- アカウント連携 --> 
                                <article class="media"> 
                                    <div class="content"> 
                                        <p> 
                                            <strong>アカウント連携</strong><br/> 
                                            <% if current_user.provider %> 
                                                <span class="has-text-success">Facebookでログイン中</span> 
                                            <% else %> 
                                                <span class="has-text-danger">アカウント連携していません。</span> 
                                            <% end %> 
                                        </p> 
                                    </div> 
                                </article> 
                            </div> 
                        </div> 
                    </div> 
                </div> 
            </div> 
            <!-- 右側 --> 
            <div class="column"> 
                <div class="columns is-multiline"> 
                    <!-- 新しいお仕事を登録 --> 
                    <div class="column is-one-third has-text-centered"> 
                        <%= link_to new_gig_path do %> 
                            <div class="card"> 
                                <div class="card-image card-content is-horizontal-center is-flex "> 
                                    <figure class="image is-128x128 "> 
                                        <%= image_tag 'icon_add.png' %> 
                                    </figure> 
                                </div> 
                                <div class="card-content"> 
                                    <strong>お仕事を新規登録する</strong> 
                                </div>    
                            </div> 
                        <% end %> 
                    </div> 
                    <!-- 登録したお仕事 --> 
                    <% current_user.gigs.each do |gig| %> 
                        <div class="column is-one-third"> 
                            <div class="card"> 
                                <div class="card-image"> 
                                    <%= link_to edit_gig_path(gig) do %> 
                                        <figure class="image is-4by3"> 
                                            <%= image_tag gig_cover(gig) %> 
                                        </figure> 
                                    <% end %> 
                                </div> 
                                <div class="card-content p-t-5 p-b-5"> 
                                    <p class="subtitle is-6 m-b-5"><%= link_to gig.title, gig_path(gig) %></p> 
                                    <span class="star-review"><i class="fa fa-star"></i> 
                                        <%= gig.average_rating %> 
                                        <span class="has-text-primary">(<%= gig.reviews.count %>)</span> 
                                    </span>                                                      
                                </div> 
                                <footer class="card-footer"> 
                                    <% basic_price = gig.pricings.find{ |p| p.pricing_type == 'basic' } %> 
                                    <a class="has-text-danger is-block card-footer-item has-text-right"> 
                                        <% if !basic_price.nil? %> 
                                            <span class="small-title">最低価格</span> 
                                            <strong><%= number_to_currency(basic_price.price) %></strong>                                            
                                        <% else %> 
                                            <strong> 
                                                <span class="small-title has-text-dark">まだ価格がありません</span> 
                                            </strong> 
                                        <% end %> 
                                    </a> 
                                </footer>  
                                
                            </div> 
                        </div> 
                    <% end %> 
                </div> 
            </div> 
            
        </div> 
    </div> 
</section> 



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



レビュー反映




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


記述追加 app\views\users\show.html.erb
175行目から255行目に記述追加しています。
 
<div class="column"> 
    <div class="columns is-multiline"> 
        <!-- 登録したお仕事 --> 
        <% @user.gigs.each do |gig| %> 
            <div class="column is-one-third"> 
                <div class="card"> 
                    <div class="card-image"> 
                        <%= link_to edit_gig_path(gig) do %> 
                            <figure class="image is-4by3"> 
                                <%= image_tag gig_cover(gig) %> 
                            </figure> 
                        <% end %> 
                    </div> 
                    <div class="card-content p-t-5 p-b-5"> 
                        <p class="subtitle is-6 m-b-5"><%= link_to gig.title, gig_path(gig) %></p> 
                        <span class="star-review"><i class="fa fa-star"></i> 
                            <%= gig.average_rating %> 
                            <span class="has-text-primary">(<%= gig.reviews.count %>)</span> 
                        </span>                                        
                    </div> 
                    <footer class="card-footer"> 
                        <% basic_price = gig.pricings.find{ |p| p.pricing_type == 'basic' } %> 
                        <a class="has-text-danger is-block card-footer-item has-text-right"> 
                            <% if !basic_price.nil? %> 
                                <span class="small-title">最低価格</span> 
                                <strong><%= number_to_currency(basic_price.price) %></strong>                                            
                            <% else %> 
                                <strong> 
                                    <span class="small-title has-text-dark">まだ価格がありません</span> 
                                </strong> 
                            <% end %> 
                        </a> 
                    </footer>  
                    
                </div> 
            </div> 
        <% end %> 
    </div> 
    <div class="card"> 
        <div class="card-header"> 
            <div class="card-header-title">最新のレビュー</div> 
        </div> 
        <div class="card-content"> 
            <!-- レビュー --> 
            <% @reviews.each do |r| %> 
                <article class="media"> 
                    <figure class="media-left"> 
                        <p class="image is-64x64"> 
                            <%= image_tag avatar_url(r.buyer), class: "is-rounded" %> 
                        </p> 
                    </figure> 
                    <div class="media-content"> 
                        <div class="content"> 
                            <p> 
                                <strong><%= r.buyer.full_name %></strong><br> 
                                <%= r.review %> 
                            </p> 
                            <small><%= time_ago_in_words(r.created_at) %></small> 
                        </div> 
                    </div> 
                    <div class="media-right"> 
                        <span class="star-review"><i class="fa fa-star"></i> <%= r.stars %></span> 
                    </div> 
                </article> 
            <% end %> 
        </div> 
    </div> 
</div> 





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

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

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

3,000円

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

タスク数: 146