##自己紹介
9月から独学でプログラミング学習を開始し、
11月からスクールを使って学習をしています。
現在はポートフォリオの作成し転職活動中です。
知識を定着させるために、学びをアウトプットしています。
また、これから学び始める方の参考になることを願っています。
##開発環境
- Ruby 3.0
- Ruby on Rails 6.0.3.4
- jQuery 3.5.1
#Ajaxでお気に入り機能を実装する
前回、Railsでお気に入り機能を実装するという記事を投稿しました。
今回は、この記事の非同期化を行います。
同時にお気に入り数のカウントも行ってみましょう!
##1.マイグレーションファイルを作成する
まずはターミナルで下記のコマンドを実行して下さい。
rails g migration AddLikersCountToMoives
そして、生成されたマイグレーションファイルを編集します。
class AddLikersCountToMovies < ActiveRecord::Migration[6.0]
def change
add_column :movies, :likers_count, :integer, default: 0
end
end
これでlikees_count
というメソッドが使用できるようになりました。
公式のGithubも合わせて参照下さい。
☆ポイント
ここでrails db:migrate
を実行しますが、
その前に、もしお気に入りの登録を行っている場合は全て解除して下さい。
default: 0
としているため、現在の状態が0になってしまいます。
このまま、お気に入り解除をすると-1のような表示になってしまいます。
##2.ビューファイルを追加する
まずは、views/movie
配下に_favorite.html.erb
というビューファイルを新しく追加します。
<% if current_user.likes?(movie) %>
お気に入り解除
<% else %>
お気に入り登録
<% end %>
<%= movie.likers_count %>
これは以前に作成したビューファイルを切り出したものに、likers_count
を追加したものになります。
それでは、以前に作成したビューファイルを編集しましょう
##3.ビューファイルの編集をする
<%= link_to favorite_movie_path(movie), remote: true do %>
<div id="favorite-movie">
<%= render partial: "movies/favorite", locals: {movie: movie}
</div>
<% end %>
まず、作成した_favorite.html.erb
をrender partial: "movies/favorite"
で読み込んでいます。
locals: {movie: movie}
はfavorite.html.erb
内のmovieにビューで使っているmovieを渡しています。
renderについてはRailsガイドを参照ください。
link_to
のオプションにremote: true
を指定しています。
これによりviews/movies/favorite.js.erb
が呼び出されるようになります。
指定したid="favorite-movie
はfavorite.js.erb
で使用します。
##4.JavaScriptファイルを作成する。
views/movies
配下にfavorite.js.erb
を作成して下さい。
内部は下記の1行だけです。
$("#favorite-movie").html("<%= j(render partial: "movies/favorite", locals: {movie: @movie}) %>");
先程のidを指定し、内部のhtmlを_favorite.html.erb
に書き換えています。
今回、jQueryを使用していますが、導入については、省略致します。
以上で機能の実装は終了です。
前回記事、Railsでお気に入り機能を実装すると合わせてご覧下さい。
また、至らない点があれば、お手数ですがご指摘下さい。
###補足①
非同期でお気に入りを行った際に、お気に入り数のカウントが、遅れてしまう可能性があります。
そのような場合、controllers/movies_controller.rb
に下記を追加して下さい。
def favorite
@movie = Movie.find(params[:id])
current_user.toggle_like!(@movie)
+ @movie.reload #この1行を追加
reload
でお気に入り処理後に再読み込みを行っています。
###補足②
お気に入り処理をeach
など繰り返し処理内で行いたいこともあると思います。
その場合は、指定したid="favorite-movie
を下記のように変更して下さい。
<%= @movies.each do |movie| %>
<div id="favorite-movie-<%= movie.id %>">
<%= render partial: "movie/favorite", locals: {movie: movie} %>
</div>
<% end %>
views/movies/favorite.js.erb
$("#favorite-movie-<%= @movie.id %>").html("<%= j(render partial: "movies/favorite", locals: {movie: @movie}) %>");
id属性にid値を指定することで、繰り返し処理内でもお気に入りの処理を行うことができます。