【Rails】 投稿時の星5段階評価機能の実装
5段階評価の実装
要件
・自身の投稿にのみ、5段階評価をつけられ、評価をつけられるタイミングは、投稿時に限定。
・本の一覧ページと詳細ページに5段階評価を表示させる。
・ユーザーの詳細ページに 5 段階評価を表示させる。
・一度評価をつけたら変えられない。(Edit ページにも星は表示されるが、変更不可)
前提
・ jQuery のインストールがされている。
5段階評価の実装方法
様々な方法があるようですが、今回は JavaScript で作成されたプラグインである Raty を使用し、最新バージョンである Raty 4系で実装を行います。
Ratyの利用手順
- githubよりダウンロードしてください。(https://github.com/wbotelhos/raty)
- ダウンロードしたら、
raty/src/images
の中にある下記3つのスターの画像を自分のapp/assets/images
フォルダに格納します。
・star-half.png
・star-on.png
・star-off.png -
src/raty.js
をapp/javascript
にコピーします。 -
app/javascript/packs/application.js
に下記を追加します。
import Raty from "raty.js"
window.raty = function(elem,opt) {
let raty = new Raty(elem,opt)
raty.init();
return raty;
}
このコードは、raty.js
という JavaScript ライブラリから Raty というオブジェクトをインポートして、グローバル変数の window.raty に設定している。
windowオブジェクトとは
・画面上に表示されているすべてのオブジェクトの親となるオブジェクト
・JavaScript のオブジェクト階層の最上位に位置する。
・ウィンドウに関する情報の取得や、ウィンドウを設定・操作する。
function(関数)とは
・様々な処理を1つにまとめて、名前をつけることができるもの。
・単調な処理を1つにまとめて、どこからでも使えるように効率化するという目的で使われている。
"star"カラムの追加
rails g migration AddStarToBooks star:string
booksテーブルに string 型の star カラムの追加します。
rails db:migrate
ストロングパラメーターへ star カラムを追記する
private
def book_params
params.require(:book).permit(:title, :body, :star)#ここのstar
end
end
permit メソッドへ追記することで'star'が保存できるようになります。
view への記述
indexとeditで使用される部分テンプレート
:
<% if book.id.nil? %>
<div class="form-group" id="star">
<%= f.label :star %>
<%= f.hidden_field :star, id: :review_star, class: 'form-control' %>
<div id="post_raty"></div>
</div>
<script>
$(document).on('turbolinks:load', function() {
let elem = document.querySelector('#post_raty');
if (elem == null) return;
elem.innerHTML = ""
let opt = {
starOn: "<%= asset_path('star-on.png') %>",
starOff: "<%= asset_path('star-off.png') %>",
starHalf: "<%= asset_path('star-half.png') %>",
scoreName: 'book[star]',
};
raty(elem, opt);
});
</script>
<% else %>
<div class="form-group">
<%= render "static.rate", book: book %>
</div>
<% end %>
新しく投稿をするときには、評価の星の評価を追加するために Raty プラグインが使用され、既存の投稿の場合は下記の_static.rate
ファイルが使用されます。
<div id="star_<%= book.id %>"></div>
<script>
$(document).on('turbolinks:load', function() {
let elem = document.querySelector('#star_<%= book.id %>');
if (elem == null) return;
elem.innerHTML = "";
let opt = {
starOn: "<%= asset_path('star-on.png') %>",
starOff: "<%= asset_path('star-off.png') %>",
starHalf: "<%= asset_path('star-half.png') %>",
score: "<%= book.star %>",
readOnly: true, #readOnlyパラメータが設定されているため、ユーザーは評価を変更できない
};
raty(elem, opt);
});
</script>
投稿のIDに応じて異なるスターの評価を表示するために使用されます。
div タグは、投稿のIDに基づいて動的に生成され、スクリプトでは、それをターゲットとして使用。最後に、評価値、readOnly オプションなどが設定された Raty プラグインをインスタンス化する。これにより、ユーザーがその投稿につけた評価が表示されます。
必要な箇所に部分テンプレートを記述
<%= render "books/static.rate", book: book %>
<%= render 'form', book: Book.new %>
:
<%= render "static.rate", book: @book %>
<%= render 'form', book: @book %>
<%= render 'form', book: @book %>
:
<%= render 'index', books: @books%>
以上になります。
Discussion