class_nameを使ったアソシエーションの組み方

こんにちは!kossyです!




本日気になったニュースはこちら
headlines.yahoo.co.jp


「どこかで人とつながりたい気持ちがちょっとある」。川崎市から来た病院職員の女性(33)はそう語った。
ハロウィーンで渋谷に来るのは昨年に続き2回目だ。普段の仕事にあまり出会いはない。
だが、渋谷で仮装していれば知らない人同士でも気軽に声を掛け合ったり、一緒に写真を撮ったりできる。
「日常ではこういうことは難しい。1年に1回だから楽しみたい」

この文章が全てを集約しているような気がします。
みなさん誰かと繋がりたくて、お祭りを楽しみたくて行っているんだと思います。

そして何年か後には自然消滅してそうな気がします。根拠は霊感ですが。










さて、今回はあるモデルが複数のモデルを持っている場合の
class_nameを使ったアソシエーションの組み方を
ブログに残してみたいと思います。




環境
Rails 5.1.6
Ruby 2.5.1
MacOS Mojave





前提

誰が誰にlikeしたのかの状態をデータベースに保存するようなモデルを組んでみたいとします。

モデル
Userモデル
Reactionモデル (to_user_id: 被likeユーザー, from_user_id: likeしたユーザー, status: like or dislike)

User has_many Reactions
という構成とします。




class_nameオプション

セオリーではReactionモデルにはbelongs_to :userと書きたくなりますが、
その場合、Railsは reaction.user と書かれると、Reactionテーブルのuser_idカラムに設定されているidと
Userテーブルのidが一致するuserを探し当てます。

belongs_to :to_user だけでは、「reaction.to_userを見つけるには、to_user_idカラムとToUserモデルを使えってことね」と
解釈するようになってしまいます。

モデル名はUserモデルになってほしいので、class_nameオプションを使用し、

reaction.rb

belongs_to :to_user, class_name: "User"
belongs_to :from_user, class_name: "User"

と記述すると、「reaction.to_userを見つけるには、to_user_idカラムとUserモデルを使えってことね」
と解釈してくれるようになります。




参考にさせていただいたサイト
Railsでbelongs_toをクラス名とは別名で持たせたい - Qiita
【Rails】多対多のアソシエーションに別名をつけたいあなたに - ひよっこエンジニアの雑多な日記
Active Record の関連付け (アソシエーション) | Rails ガイド