ume

has_many :following, through: :active_relationships, source: :followed意味

対象者

  • rails tutorial14章取り組んでいる方

コードの意味

user.rb

class User < ApplicationRecord
  has_many :following, through: :active_relationships, source: :followed
end 

このコードを見て混乱したので理解を定着させたいので記事にします。

前提(以下のような状態)

今2つテーブル(UserテーブルとRelationshipテーブル)があり多対多の関係である 要はUserテーブルの外部キー(user_id)をRelationshipテーブルでfollower_idとfollowed_idという名前で持たせている.

relationship.rb

class Relationship < ApplicationRecord
  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
  validates :follower_id, presence: true
  validates :followed_id, presence: true
end

user.rb

class User < ApplicationRecord
  has_many :active_relationships, class_name: "Relationship",
                                  foreign_key: "follower_id",
                                  dependent: :destroy
has_many :following, through: :active_relationships, source: :followed

このコードの意味( has_many :following, through: :active_relationships, source: :followed)

⇨ユーザーがフォローしているユーザーを特定するためのメソッド.

まずhas_manyはメソッドを作成することができるメソッドである.
つまりhas_many :following, これで

userインスタンス.following

といった感じでメソッドとして使用できるようになる。 上記のメソッドを使用した場合↓と同じ意味

@user = User.first 
@user.active_relationships.map(&:followed)

User.firstでRelationshipテーブルの一番最初のレコードつまりId1(主キー)のものを取得し@userに代入する.

@user.active_relationshipsでRelationshipテーブルのfollower_id(user_idのこと)が1のレコードを全て取得する。つまり↓2つのレコードが配列となって返される その配列(2つのレコードが入っている)に対し.mapメソッドで1つずつ取り出し(&:followed)で各それぞれのレコードにfollowedメソッドを行う。 mapメソッドの使い方は↓.
【Ruby】 mapメソッドの基礎から応用の使い方まとめ | Pikawaka followedメソッドはRelationshipテーブルのfollowed_id(Userテーブルの外部キー)からUserテーブルのユーザーを特定するメソッド 毎回ユーザーがフォローしているユーザーを特定するために↓のような長いコードを書くのが嫌なので

@user = User.first 
@user.active_relationships.map(&:followed)
  has_many :following, through: :active_relationships, source: :followed

このように書きfollowingメソッドはactive_relationships(Relationテーブル)を経由してフォローしているユーザーを特定していることを表す。