はじめに
プログラミング学習を始めて2ヶ月目になります。
学習したことを自分なりに解釈理解し、アウトプットできればと思いQiitaを始めてみました。
今回実装していく流れ
- 事前準備(jQuery、raty.jsの導入)
- 投稿フォームに星レビュー機能の追加
- 投稿の詳細画面での星レビュー表示
- 投稿の一覧画面での星レビュー表示
開発環境
- ruby 2.6.3p62
- Rails 6.1.4
前提モデル
〜事前準備〜
1. jQueryを導入
rails6では、yarnでjqueryをインストールしてください。
yarn add jquery
次に、webpackerの設定ファイルで、jQueryを管理下に追加するための記述を追加します。
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を呼び出します。
省略
#追記
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
以上で raty.jsの導入は完了です。
投稿フォームに星レビュー機能の追加
1. "star"カラムの追加
ターミナルにて、カラム追加のコマンドを実行。
rails g migration AddStarToBooks star:string
これでbooksテーブルにstring型のstarカラムの追加用マイグレーションファイルが作成されます。
rails db:migrate
次に作成したマイグレーションファイルをマイグレートしていきます。
カラムを追加したER図
2."star"カラムを保存できるようにデータ操作を許可する。
.
.
.
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を埋め込み
<%= 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カラムへ保存します。
ってことだと思います。
これで星レビューが投稿できるようになっていると思います。
次は投稿したレビューを表示できるようにしていきます。
参考記事
- ブラウザバックで星が増える不具合の参考記事
投稿の詳細画面での星レビュー表示
<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>
$('#star-rate<%= @book.id %>').empty(); #これがないとブラウザバックで星が増え続ける不具合が発生します。詳しくは参考にした記事を参照ください。
readOnly: true, #読み取り専用、編集できないようにする。
score: <%= @book.star %>, #@book= Book.find(params[:id])のstarカラムを取り出す。
これで投稿の詳細画面での表示はできたと思います。
次は、投稿一覧ページへ星レビュー表示させていきます。
投稿の一覧画面での星レビュー表示
<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>
追加する記述は、詳細ページとほとんど同じ内容になりまね。
以上で完成です。
次の記事、ソート機能の実装をやっています。
完成イメージ
参考した記事