1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Ajax]いいね機能を非同期にした

Last updated at Posted at 2021-09-02

はじめに

本記事では、非同期通信についてを記述します。
本日実装しました。

前提

いいね機能は同期通信で実装しています。

また、オリジナルアプリ開発途中で不要なコードが多いので、
省略は多めですが、該当箇所は記載します。

いいね機能

ビュー

いいねを表示しているビューindex.html.erb

<div class="food-likes-<%= food.id %>">にしないと、
どのfood(投稿)に対するいいねなのか分かりません。
試しに-<%= food.id %>を抜いたところ、
全部の投稿が同時にいいね出来る仕様になってしまいました。
ふとlocalsメソッドの意味を忘れたので、調べましたw
【Rails】 部分テンプレートの使い方を徹底解説!

省略

<% @foods.each do |food| %>
         
省略
              
  <div class="food-likes-<%= food.id %>">
     <%= render partial:"likes/like", locals: {food: food} %>
  </div>

省略

<% end %>

省略

コントローラー

@foods=~に関しては前回の投稿を参照ください。

foods_controller.rb
  def index
    @foods = Food.order("created_at DESC").where(user_id: [current_user.id,*current_user.following_ids]).where(created_at: from...to)
    @like = Like.new
  end

createはいいねdestroyはいいね解除になります。
同期通信の場合、endの前にredirect to~がありますが、必要ないので消します。

likes_controller.rb
class LikesController < ApplicationController

  def create
    @food = Food.find(params[:food_id])
    @like = current_user.likes.create(food_id: params[:food_id])
  end

  def destroy
    @food = Food.find(params[:food_id])
    @like = Like.find_by(food_id: params[:food_id],user_id: current_user.id)
    @like.destroy
  end
end

モデル

food.rb
省略
  belongs_to :user
  has_many :likes
  has_many :liked_users, through: :likes, source: :user
省略
like.rb
class Like < ApplicationRecord
  belongs_to :food
  belongs_to :user
  
  validates_uniqueness_of :food_id, scope: :user_id
end

部分テンプレートのビュー

<%= render partial:"likes/like", locals: {food: food} %>likes/like

remote: trueすることで、
リクエストがjs形式になります。

注意点としては、local :trueは消しましょう。

<h2 class="food-likes-index">KALIKE
  <%= food.likes.count %>
</h2>
<% if user_signed_in? %>
  <% if current_user.already_liked?(food) %>
    <%= link_to "いいねを取り消す", food_likes_path(food,@like), method: :delete, remote: true %>
  <% else %>
    <%= link_to "いいね", food_likes_path(food), method: :post, remote: true %>
  <% end %>
<% end %>

js.erbファイル

リクエストがjsなので、js.erbでお出迎えです。
create.js.erb

$('.food-likes-<%= @food.id %>').html("<%= j(render partial: 'likes/like', locals: {food: @food}) %>")

destroy.js.erb

$('.food-likes-<%= @food.id %>').html("<%= j(render partial: 'likes/like', locals: {food: @food}) %>")

jについては、escape_javascriptの略です。

escape_javascriptは、改行やエスケープ処理をしてくれます。
【Rails】 remote: trueでフォーム送信をAjax実装する方法とは?

以上です。
いかがでしょうか。

終わりに

割と悩みました。
特にjs.erbファイルは初見だったので良い経験ができて楽しかったです。

いいねができたので、
フォロー機能とコメント機能も非同期にしてみようとコード書いてみたら、
そこそこすんなり(コメント機能はやや悩んだ)できました。

次回以降フォロー機能とコメント機能の非同期通信についても書こうと思います。

以下参考サイトです。
【Rails】 remote: trueでフォーム送信をAjax実装する方法とは?
RailsとAjaxを使ったいいね機能の非同期通信
Railsガイド
JavaScriptで関数のエイリアスを作る方法を現役エンジニアが解説【初心者向け】
HTML特殊文字のエスケープ
パーシャルをレンダリングする前にescape_javascriptを使用するのはなぜですか?

明日も頑張ります!!

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?