1
5

More than 3 years have passed since last update.

【Rails】コメント機能に星評価機能を導入する

Last updated at Posted at 2021-08-14

はじめに

Raty.jsというものを使い、コメント形式で投稿を星評価できるようにします。
また、多数のユーザーからの星評価の平均を出力することもできたので、そちらも合わせて紹介します。
image.png

使用環境

Ruby on Rails 6

前提

・CRUD機能を実装している事
・deviseを導入している事
・コメント機能を実装している事

モデルの設計

・Userモデル(deviseで作成)
・Tweetモデル
・Commentモデル

Commentモデルにrateカラムを設置

ターミナル/コマンドプロンプト
rails g migration AddRateToComments rate:float

Raty.jsを用いる際にはrateカラムが大切になってきます。今回は「星1.5」などにも対応するため、float型を用いています。

Commentモデルにバリデーションを追加

app/models/comment.rb
validates :rate, numericality: {
    less_than_or_equal_to: 5,
    greater_than_or_equal_to: 1}, presence: true

ここでは、星が1~5までで保存できるようになっています。

表示するために星の画像を追加

https://github.com/wbotelhos/raty/tree/master/lib/images
ここから星の画像をダウンロードできます!ダウンロードした画像は、「app/assetes/images」直下に保存します。

jQueryの導入

ターミナル/コマンドプロンプト
yarn add jquery

yarn addコマンドは、パッケージのインストールと共に、package.jsonへバージョンを書き込んでくれます。

次に、webpackerの設定ファイルで、jQueryを管理下に追加するための記述をします。

config/webpack/environment.js
const { environment } = require('@rails/webpacker')
追記
const webpack = require('webpack')

environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery',
    jquery: 'jquery/src/jquery',
  })
)
ここまで
module.exports = environment

最後に、jQueryを呼び出します。

app/javascript/packs/application.js
省略

window.$ = window.jQuery = require('jquery'); 追記

Raty.jsの導入

app/javascript/packsにraty.jsというファイルを作成します。

次に下記URLのjsコードをraty.jsにコピーする。
https://github.com/wbotelhos/raty/blob/master/lib/jquery.raty.js

最後にapplication.js に下記を追加します。

app/javascript/packs/application.js
window.$ = window.jQuery = require('jquery'); 
require('packs/raty') 追記

Controller設計

app/controllers/tweets_controller
省略

def show
     @tweet = Tweet.find(params[:id])
     @comments = @tweet.comments
     @comment = Comment.new
end

省略
app/controllers/comments_controller
def create
     tweet = Tweet.find(params[:tweet_id])
     comment = tweet.comments.build(comment_params) #buildを使いcontentとtweet_idの二つを同時に代入
     comment.user_id = current_user.id
     if comment.save
         flash[:success] = "コメントしました"
         redirect_back(fallback_location: root_path)
     else
         flash[:success] = "コメントできませんでした"
         redirect_back(fallback_location: root_path)
     end
 end

 private
 def comment_params
     params.require(:comment).permit(:content, :rate)
 end

View設計

app/views/tweets/_rate_average.html.erb
<div class="average-review-rating" data-score=<%= @comments.average(:rate) %>></div>

<script>
  $('.average-review-rating').raty({
    readOnly: true,
    starOn: "<%= asset_path('star-on.png') %>",
    starOff: "<%= asset_path('star-off.png') %>",
    starHalf: "<%= asset_path('star-half.png') %>",
    score: function() {
      return $(this).attr('data-score')
    }
  });
</script>
app/views/tweets/show.html.erb
<%= render 'rate_average' %>
<div class="comment-container">
  <% @comments.each do |c| %>
    <div class="pt-2 px-2" style="background-color: #fffffe; border: 2px solid #272343; border-radius: 2px;">
        <div class="review-rating" data-score="<%= c.rate %>">評価:<%= c.rate %></div>

        <div class="text-left">
            <p>投稿者:<%= c.user_id %></p>
            <p><%= c.content %></p>
        </div>

        <div class="text-right">
            <p>
                投稿日:<%= c.created_at.strftime('%Y/%m/%d') %>
            </p>
        </div>
    </div>

    <div class="pb-2"></div>

  <% end %>

  <%= form_with(model: [@tweet, @comment], local: true) do |f| %>

    <%= f.text_area :content, rows:'5', placeholder: "コメント", class: "form-control form-control-sm" %>
    <div id="rating-form">
        <label>評価:</label>
        <%= f.hidden_field :rate, :value => 'score' %>
    </div>

    <%= f.submit "投稿する" %>
  <% end %>
</div>

<script>
    $('#rating-form').raty({
        starOn: "<%= asset_path('star-on.png') %>",
        starOff: "<%= asset_path('star-off.png') %>",
        scoreName: 'comment[rate]'
    });
</script>

参考記事

https://nllllll.com/ruby-on-rails/rails-raty-js-review/
https://qiita.com/nozomi_nozomi/items/eb6848c6025ca63af1c4

1
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5