LoginSignup
2
3

More than 1 year has passed since last update.

[ruby on rails]いいね機能つける→非同期通信にする

Last updated at Posted at 2021-07-06

初めに

プログラミング学習初めて1ヶ月ほどです。
自身のアウトプット、不明点あらい出しのためにアウトプットしています。

*まず最初に普通に「いいね」機能を作り、
その後、非同期通信にしています。

いいね機能つける not非同期通信

前回の記事でコメント機能をつけています。
本の投稿サイトに以下のようないいね機能をつけます。

routes.rb
resources:books,only:[:new,:create,:index,:show,:destroy,:edit,:update]do
    resource:favorites,only:[:create,:destroy]
    resources:book_comments,only:[:create,:destroy]
  end

resouceとresoucesの違い

以下の記事で理解できました。
favoriteのshowページを作成することもないですし、idの受け渡しが発生しないので、
resorceで記述します。

https://techtechmedia.com/resources-resource-difference/

テーブルとモデルの作成

必要なのは??
1、いいね自体のid(integer型)
2、誰がいいねしたかのuser_id
3、どの投稿にいいねしたかの book_id
2,3は外部キーですよね。

rails g model Favorite user_id:integer book_id:integer
rails db:migrate

アソシエーション

コメントの時と同様にアソシエーションを追記します。

user.rb
class User < ApplicationRecord


has_many :favorites, dependent: :destroy

book.rb
class Book < ApplicationRecord
  belongs_to:user

validates :title, presence: true
validates :body, presence: true,length:{maximum:200}
has_many :book_comments, dependent: :destroy
has_many :favorites, dependent: :destroy  #追記


 def favorited_by?(user)
    favorites.where(user_id: user.id).exists?
 end  #追記

end

 favorited_byってなに?whereってなに??

まずwhere
モデル名.where(任意のカラム名: 格納されている値)となるそう。
既にいいね済みであれば、複数回いいねは出来ません

favorite.rb
class Favorite < ApplicationRecord
  belongs_to:user
  belongs_to:book
end

コントローラー作成

rails g controller Favorites create destroy

Viewの作成

本の投稿一覧ページに以下の記載をします。

<% if @books.favorited_by?(current_user) %>

   <%= link_to book_favorites_path(@books), method: :delete do %>
   ♥<%= @books.favorites.count %>
   <% end %>

   <% else %>

    <%= link_to book_favorites_path(@books), method: :post do %>
     ♡<%= books.favorites.count %>
     <% end %>

  <% end %>

コントローラー記述

class FavoritesController < ApplicationController

  def create
    book = Book.find(params[:book_id])
    favorite = current_user.favorites.new(book_id: book.id)
    favorite.save
    redirect_to request.referer
  end

  def destroy
    book = Book.find(params[:book_id])
    favorite = current_user.favorites.find_by(book_id: book.id)
    favorite.destroy
    redirect_to request.referer
  end

end

一行ずつ、解説?していきます。

Create

book = Book.find(params[:book_id])
まず、 「いいね」する本の投稿に紐付いているbook_idをparams:で取得します。

favorite=current_user.favorites.new(book_id book.id)
ここの記述は

コメント機能との違い

コメント機能ではdestroyで2つのidを取得していましたが、今回は1つしか取得していません・・・。
なぜかというと、resouceでルーティングを作成してるのでfavoriteコントローラーはidの受け渡しをやってくれていない からだと思います。一方で、コメントのはresoucesで作成しており、book_commentのidとbookのidを両方取得していると。

出来上がりイメージ

スクリーンショット 2021-07-06 9.58.40.png

非同期通信にする

ここの記事がとても参考になります。
この通り行えば非同期通信ができます!

非同期通信の簡単な流れ(個人メモ)

1、いいねのview部分を部分テンプレートにする
2、いいねを押す(外す)記述である<%= link_to〜の部分に、remote trueを加える (非同期します!宣言)
3,コントローラーにあるredirect to~やらrender ~は消す!
2と3をやることで、次のリクエストがjsファイルに変わります。
それまでhtmlファイル探してたのが、「jsファイルどこ〜〜?」ってやってくれるようになる。
4、favoritesフォルダにアクション名と同じjsファイルを作成。必ずアクション名と一致させる!!

いいねの一覧表示

あるユーザーがいいねした記事の一覧表示の説明については以下で行っています。

2
3
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
2
3