LoginSignup
10
13

More than 1 year has passed since last update.

【Rails】raty.jsを用いた星5レビュー機能の実装

Last updated at Posted at 2022-03-09

はじめに

プログラミング学習を始めて2ヶ月目になります。
学習したことを自分なりに解釈理解し、アウトプットできればと思いQiitaを始めてみました。

今回実装していく流れ

  • 事前準備(jQuery、raty.jsの導入)
  • 投稿フォームに星レビュー機能の追加
  • 投稿の詳細画面での星レビュー表示
  • 投稿の一覧画面での星レビュー表示

開発環境

  • ruby 2.6.3p62
  • Rails 6.1.4

前提モデル

Bookers2のER図before.drawio.png

〜事前準備〜

1. jQueryを導入

rails6では、yarnでjqueryをインストールしてください。

ターミナル
yarn add jquery

次に、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');

2. raty.jsの導入

星レビューするときの、星画像をこちらのgithubでダウンロードします。

 https://github.com/wbotelhos/raty/tree/master/lib/images

今回使う画像は
star-on.png
star-off.png
になります。
ダウンロードした画像は、
assets/imagesフォルダの中へ格納します。

raty.jsファイルの作成

app/javascript/packs に raty.jsを作成。

次に下記URLのjsコードを先ほど作成したraty.jsに貼り付けます。
https://github.com/wbotelhos/raty/blob/master/lib/jquery.raty.js

スクリーンショット 2022-03-09 16.43.09.png

以上で raty.jsの導入は完了です。

投稿フォームに星レビュー機能の追加

1. "star"カラムの追加

ターミナルにて、カラム追加のコマンドを実行。

rails g migration AddStarToBooks star:string

これでbooksテーブルにstring型のstarカラムの追加用マイグレーションファイルが作成されます。

rails db:migrate

次に作成したマイグレーションファイルをマイグレートしていきます。

カラムを追加したER図
Bookers2のER図after.drawio.png

2."star"カラムを保存できるようにデータ操作を許可する。

controllers/books_controller.rb
.
.
.
def create
    @book = Book.new(book_params)
    @book.user_id = current_user.id
    if @book.save
      redirect_to book_path(@book), notice: "You have created book successfully."
    else
      @books = Book.all
      render 'index'
    end
  end
.
.
.

private

  def book_params
+  params.require(:book).permit(:title, :body, :star)
  end
.
.
.
end

booksコントローラーのストロングパラメーターへstarカラムを追記します。
permitメソッドへ追記することで'star'が保存できるようになりました。
 次は、保存はできるようになっていますが、星レビューの投稿ができないので
投稿フォームviewへ星レビューする場所を作っていきます。

3.投稿フォームのviewへ星レビュー機能のjavascriptを埋め込み

views/books/_form.html.erb
<%= form_with model:book,local:true do |f| %>
  <div class="form-group">
    <%= f.label :title %>
    <%= f.text_field :title, class: 'form-control book_title' %>
  </div>
  <div class="form-group">
    <%= f.label :opinion %>
    <%= f.text_area :body, class: 'form-control book_body' %>
  </div>
  <div class="form-group">
    <%= f.submit class: 'btn btn-success' %>
  </div>

ーーーーーーーーーーーーーーここからが星レビュー機能ーーーーーーーーーーーーーーーー
  <div class="form-group row" id="star">
    <%= f.label :star,'評価 ', class:'col-md-3 col-form-label' %>
    <%= f.hidden_field :star, id: :review_star %>
    </div>
  <script>
    $('#star').empty();
  $('#star').raty({
    size     : 36,
    starOff:  '<%= asset_path('star-off.png') %>',
    starOn : '<%= asset_path('star-on.png') %>',
      scoreName: 'book[star]', 
    half: false,
  });
  </script>
ーーーーーーーーーーーーーーここまでが星レビュー機能ーーーーーーーーーーーーーーーー
<% end %>
$('#star').empty();             #これがないとブラウザバックで星が増え続ける不具合が発生します。詳しくは参考にした記事を参照ください。 
scoreName: 'book[star]',  #これがbookモデルのstarカラムへ値を保存という意味になる。
half: false,                          #今回は5段階評価で⭐️半分評価は入力できないように設定します。

id="star"で "star" というid名をつけて
$('#star').raty(      で "star" に"raty.js"を以下の内容で適用させ、
scoreName: 'book[star]' で bookモデルのstarカラムへ保存します。
ってことだと思います。

これで星レビューが投稿できるようになっていると思います。
次は投稿したレビューを表示できるようにしていきます。

参考記事

  • ブラウザバックで星が増える不具合の参考記事

投稿の詳細画面での星レビュー表示

views/books/show.html.erb
<div class='container'>
  <div class='row'>
    <div class='col-md-3'>
      <h2>User info</h2>
      <%= render 'users/info', user: @book.user %>
      <h2 class="mt-3">New book</h2>
      <%= render 'form', book: Book.new %>
    </div>
    <div class='col-md-8 offset-md-1'>
  		<h2>Book detail</h2>
  		<table class='table'>
  		  <tr>
          <td><%= link_to(@book.user) do %>
            <%= image_tag @book.user.get_profile_image, size:"100x100" %><br>
            <%= @book.user.name %>
            <% end %>
          </td>
          <td><%= link_to @book.title, @book %></td>
          <td><%= @book.body %></td>
          <td class=<%= "favorite-" + @book.id.to_s %> >
            <%= render "favorites/btn", book: @book %>
          </td>
          <td class="book-comments-counter">
            <%= render "book_comments/counter", book: @book %>
          </td>
ーーーーーーーーーーーーーーーーーーーーーここから星レビュー機能の追加ーーーーーーーーーーーーーーーーーーーーーーーーーー
          <td>
            <div id="star-rate<%= @book.id%>"></td>
             <script>
              $('#star-rate<%= @book.id %>').empty();
              $('#star-rate<%= @book.id%>').raty({
                 size      : 36,
                 starOff   : '<%= asset_path('star-off.png') %>',
                 starOn    : '<%= asset_path('star-on.png') %>',
                 half      : false,
                 readOnly: true,
                 score: <%= @book.star %>,
               });
             </script>
          </td>
ーーーーーーーーーーーーーーーーーーーーここまで星レビュー機能の追加ーーーーーーーーーーーーーーーーーーーーーーーーーーー
          <% if @book.user == current_user %>
            <td><%= link_to 'Edit', edit_book_path(@book), class: "btn btn-sm btn-success edit_book_#{@book.id}" %></td>
            <td><%= link_to 'Destroy', @book, method: :delete, data: { confirm: '本当に消しますか?' }, class: "btn btn-sm btn-danger destroy_book_#{@book.id}" %></td>
          <% end %>
        </tr>
      </table>

      <div class="book-comments-index">
        <%= render "book_comments/index", book: @book %>
      </div>

      <%= render "book_comments/form", book: @book, book_comment: @book_comment %>

    </div>
  </div>
</div>
point

$('#star-rate<%= @book.id %>').empty();     #これがないとブラウザバックで星が増え続ける不具合が発生します。詳しくは参考にした記事を参照ください。 
readOnly: true,                                           #読み取り専用、編集できないようにする。
score: <%= @book.star %>,                                 #@book= Book.find(params[:id])のstarカラムを取り出す。

これで投稿の詳細画面での表示はできたと思います。

次は、投稿一覧ページへ星レビュー表示させていきます。

投稿の一覧画面での星レビュー表示

views/books/_index.html.erb
<table class='table table-hover table-inverse'>
  <thead>
    <tr>
      <th></th>
      <th>Title</th>
      <th>Opinion</th>
      <th colspan="3"></th>
    </tr>
  </thead>
  <tbody>
    <% books.each do |book| %>
      <tr>
        <td><%= link_to(book.user) do %>
          <%= image_tag book.user.get_profile_image, size:'50x50' %>
          <% end %>
        </td>
        <td><%= link_to book.title,book, class: "book_#{book.id}" %></td>
        <td><%= book.body %></td>
        <td class=<%= "favorite-" + book.id.to_s %> >
            <%= render "favorites/btn", book: book %>
        </td>
ーーーーーーーーーーーーーーーーーーーーーここから星レビュー機能の追加ーーーーーーーーーーーーーーーーーーーーーーーーーー
        <td>
          <div id="star-rate<%= book.id%>"> </td>
          <script>
            $('#star-rate<%= book.id %>').empty();
            $('#star-rate<%= book.id%>').raty({
              size      : 36,
              starOff   : '<%= asset_path('star-off.png') %>',
              starOn    : '<%= asset_path('star-on.png') %>',
              half      : false,
              readOnly: true,
              score: <%= book.star %>,
            });
          </script>
          </div>    
ーーーーーーーーーーーーーーーーーーーーーここまで星レビュー機能の追加ーーーーーーーーーーーーーーーーーーーーーーーーーー
        <td><%= render "book_comments/counter", book: book %></td>
      </tr>
    <% end %>
  </tbody>
</table>

追加する記述は、詳細ページとほとんど同じ内容になりまね。
以上で完成です。

次の記事、ソート機能の実装をやっています。

完成イメージ

bookers.gif

参考した記事

10
13
1

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
10
13