LoginSignup
5
4

More than 3 years have passed since last update.

Railsでいいね機能のAjax処理を実装してみた

Last updated at Posted at 2020-11-08

はじめに

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.erbrenderさせます。

app/views/posts/show.html.erb
# ・・・省略

<div class="post-like mr-auto">
  <%= render partial: 'likes/like', locals: { post: @post, like: @like } %>
</div>

# ・・・省略

いいね機能のdeletepostの引数にremote: trueを追加してAjax機能を追加します。

app/views/likes/_like.html.erb
<% 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のメソッドで定義されたインスタンス変数を使うことができます。これは便利ですね。

app/views/likes/destroy.js.erb
$('.post-like').html('<%= j(render partial: 'likes/like', locals: { post: @post, like: @like }) %>');

app/views/likes/create.js.erb
$('.post-like').html('<%= j(render partial: 'likes/like', locals: { post: @post, like: @like }) %>');

できたもの

できたものは下記です。
ページ遷移せずに動いていることを確認できました。

like-ajax.gif

上記の実装で動作しない場合

動作しない原因は、ViewでjQueryが使えないということが考えられるので、下記の実装がされているか確認しましょう。

参考:jQuery and $ not defined in like.js.erb returned from AJAX call

app/javascript/packs/application.js
// Enable jQuery in the .js.erb file
global.$ = jQuery;
config/webpack/environment.js

//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

5
4
0

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
5
4