質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.11%

railsで、いいねをしているかどうかの判定メソッドについて

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 78

fork_

score 30

簡単なCRUDアプリケーションで、いいね機能をミニマムに作成中です。
qiita等の記事を参考にさせていただき、いいねをしているかどうかの判定メソッドをUserモデルに書いています。
他の記事でも拝見するこのメソッドですが、
self.favorites.exists?(recipe_id: recipe.id)
は具体的に何を示しているのでしょうか。
何故(recipe_id: recipe.id)と引数を取っているのでしょうか。
selfはUserモデル自身を示している認識です。

イメージ説明

#Userモデル
class User < ApplicationRecord

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

         has_many :recipes, dependent: :destroy
         has_many :favorites, dependent: :destroy

  def already_favorited?(recipe)
    self.favorites.exists?(recipe_id: recipe.id)
  end

end
#Favoriteモデル
class Favorite < ApplicationRecord
  belongs_to :user
  belongs_to :recipe

  validates_uniqueness_of :recipe_id, scope: :user_id
end
#レシピモデル
class Recipe < ApplicationRecord
  belongs_to :user
  has_many :favorites, dependent: :destroy

  with_options presence: true do
    validates :title
    validates :body
  end
end
<h1>recipe#index</h1>
<p>Find me in app/views/recipe/index.html.erb</p>

<% @recipes.each do |recipe| %>
  <%= recipe.user.name %>
  <%= recipe.title %>
  <%= recipe.body %>


    <% if Favorite.find_by(user_id: current_user.id, recipe_id: recipe.id) %>
    <%= link_to "いいねを外す", recipe_favorites_path(recipe), method: :delete %>
    <% else %>
    <%= link_to "いいね", recipe_favorites_path(recipe), method: :post %>
    <% end %>
    <%= recipe.favorites.count %>
<% end %>

==============================================
補足ですが、<% if current_user.already_favorited?(recipe) %>メソッドを使用せずに、view側で<% if Favorite.find_by(user_id: current_user.id, recipe_id: recipe.id) %>としても同じ挙動になりました。
この書き方の方が個人的にしっくりくるのですが、これは正しい書き方なのでしょうか。
Favoriteモデルの中に、ログインしているユーザーのIDと、レシピIDが入っていたら「いいね」をしているとみなす。そうでなかったら「いいね」を表示させる、という認識です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

モデルの関連定義部分を載せてください

修正依頼に書くつもりが間違えて回答に書いてしまったので、ついでですから「多分こうなってるよな」という推定で書きます
修正:コメント欄の説明に基づいて修正しました

「良いねしているか」は「私がどれかのrecipeに一つでも良いねしているか」ではなく、「このrecipeに」だと思います。
ですので、self.favorites.exists?(recipe_id: recipe.id) は
私(self)が良いねした中で(favorites)、良いねの相手が そのrecipe(recipe_id: recipe.id) なものは存在するか?
をDBに問い合わせています。

違和感が有るのは、Tweetの作成者は tweet.なんとか_id になってると思います。 ですので、self.favorites.exists?(recipe_id: tweet.なんとか_id)ならわかるのですが、それを recipe(というUserのインスタンス)にわざわざ直しているのがはて、、です。 このcodeに至る前に、recipeを作っておくわけが有るなら納得ですが。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/29 23:15 編集

    せっかくお答えいただいたのに、自分のミスで分かりづらくしてしまい大変申し訳ありません。
    自分のミスで、ER図にTweetと書いていました。
    最初から、RecipeモデルとUserモデルとFavoriteテーブルの3つで成り立っている想定です。
    もしよろしければ、再度レビューの方お願いしたく存じます。

    キャンセル

  • 2020/07/01 14:13

    ありがとうございます。
    favoritesテーブルの中に、recipe_idは既に存在しているか?を示している、という理解で齟齬ありませんでしょうか。

    キャンセル

  • 2020/07/01 14:38

    はい

    キャンセル

  • 2020/07/01 14:51

    ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる