はじめに
Railsでいいね機能を実装していたのですが、この機能を使うと下記のような問題が発生していました。
- ページ全体をレンダリングし直すため、無駄な処理を伴ってしまう。
- ページ遷移が伴ってしまうため、ページ下部でlikeやコメントをしてもページの一番上に遷移してしまい、ユーザービリティを下げている。
そのため、Ajax機能追加し、ページ遷移を伴わないようにしてユーザービリティをあげようと思いました。
最初考えた実装方法は、JavaScript・jQueryを使って、Ajax処理を発火していく方法がベストなのかなと思ったのですが、調べていくと、Railsには、link_to
などのメソッドにremote: true
を引数で付けるとAjax処理を使えるようになるとのことでした。最初考えてた実装方法と違って、簡潔だったので、さっそくその方法で実装してみました。
前提
- 投稿機能・いいね機能は既に実装済み。
- 実装しているいいね機能は、いいねボタンを押下すると、ページ遷移が伴うタイプのもの。
- 上記に対して、Ajax処理で、非同期通信で実装を行うものとします。この記事はその実装で行った手順の紹介です。
環境・バージョン
- Ruby 2.6.3
- Rails 6.0.2.1
- jQuery 3.5.1
実装
まず、app/views/posts/show.html.erb
にいいねボタンapp/views/likes/_like.html.erb
をrender
させます。
# ・・・省略
<div class="post-like mr-auto">
<%= render partial: 'likes/like', locals: { post: @post, like: @like } %>
</div>
# ・・・省略
いいね機能のdelete
とpost
の引数にremote: true
を追加してAjax機能を追加します。
<% if current_user.already_liked?(post) %>
<%= link_to 'Like', post_like_path(post, like), method: :delete, class:'post-like__cancel', remote: true %>
<% else %>
<%= link_to 'Like', post_likes_path(post), method: :post, class:'post-like__enable', remote: true %>
<% end %>
追加することで、それぞれのリンク押下後に下記の処理を実行することができようになります。
-
delete
メソッド→app/views/likes/destroy.js.erb
のファイルを実行 -
post
メソッド→app/views/likes/create.js.erb
のファイルを実行
次に、js.erb
ファイルは、下記のコードのように@post
や@like
などのController
のメソッドで定義されたインスタンス変数を使うことができます。これは便利ですね。
$('.post-like').html('<%= j(render partial: 'likes/like', locals: { post: @post, like: @like }) %>');
$('.post-like').html('<%= j(render partial: 'likes/like', locals: { post: @post, like: @like }) %>');
できたもの
できたものは下記です。
ページ遷移せずに動いていることを確認できました。
上記の実装で動作しない場合
動作しない原因は、ViewでjQueryが使えないということが考えられるので、下記の実装がされているか確認しましょう。
参考:jQuery and $ not defined in like.js.erb returned from AJAX call
// Enable jQuery in the .js.erb file
global.$ = jQuery;
//jQuery & Bootstap's JavaScript
const webpack = require('webpack')
environment.plugins.prepend(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery', //<= 記述されているか確認
Popper: 'popper.js'
})
)
さいごに
他にも応用して、フォロー機能やコメントも実装できました。
今後は、検索機能も作っていくので、Ajaxも使っていこうと思います。
参考記事
Railsで remote: true と js.erbを使って簡単にAjax(非同期通信)を実装しよう!(いいね機能のデモ付)
jQuery and $ not defined in like.js.erb returned from AJAX call