has_many :through のNested Associations
RailsTutorialで訳がわからんところがあったのでメモ
Chap 12 - Listing 12.8: Adding the User model following association.
app/models/relationship.rb
class Relationship < ActiveRecord::Base
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
end
class Relationship < ActiveRecord::Base
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
end
ときて
class User < ActiveRecord::Base
has_many :microposts, dependent: :destroy
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
.
.
.
end
↑となるが。class Userの中はなぜ
has_many :active_relationships, class_name: "Relationship",...
has_many :following, through: :relationships, ...
↑じゃないのかなと。ていうかhas_manyで事前に定義したAssocって使えるの?なんで?
ActiveRecord::Associations::ClassMethods
の
activerecord/lib/active_record/associations.rb
をみると。
Nested Associations
You can actually specify any association with the :through option, including an association which has a :through option itself.
Throughに入れるAssociationはなに使ってもいいお。(^ω^ ≡ ^ω^)
ということだそうで。
以下2つは同じことらしい
class Author < ActiveRecord::Base
has_many :posts
has_many :comments, through: :posts
has_many :commenters, through: :comments
end
class Post < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :commenter
end
@author = Author.first
@author.commenters # => People who commented on posts written by the author
class Author < ActiveRecord::Base
has_many :posts
has_many :commenters, through: :posts
end
class Post < ActiveRecord::Base
has_many :comments
has_many :commenters, through: :comments
end
class Comment < ActiveRecord::Base
belongs_to :commenter
end
じゃあ書きなおしてみる
class Author < ActiveRecord::Base
has_many :posts
has_many :comments, through: :posts
has_many :commenters, through: :comments
end
class Post < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :commenter
end
@author = Author.first
@author.commenters # => People who commented on posts written by the author
class Author < ActiveRecord::Base
has_many :posts
has_many :commenters, through: :posts
end
class Post < ActiveRecord::Base
has_many :comments
has_many :commenters, through: :comments
end
class Comment < ActiveRecord::Base
belongs_to :commenter
end
ソースコードとか読んでみたけどいまいちよくわからんし。
pryでちまちまプロセスを追ってみたけどヒントにもならず。
ソースの仕組みを書いたブログもあったけどそれでもよくわからない。
とりあえずこのあたりは「こういうふうに動く」と覚えとくかなー
class User < ActiveRecord::Base
has_many :microposts, dependent: :destroy
#チュートリアルのやりかた
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id", dependent: :destroy
has_many :followings, through: :active_relationships, source: :followed
#書き換え1
#relationships が class Relationshipと同じ名前
# class_name で「これはエイリアス」と言ってやらなくて良い
has_many :relationships, foreign_key: "follower_id"
has_many :followings1, through: :relationships, source: :followed
#書き換え2
#ひとつ目はfollower なのに foreign_key: follower_idを指定しないと動かない
#2つ目はfollowed とfollowed_idと同じ名前なのでsource:でidを指定しなくて良い。
has_many :follower, class_name: "Relationship", foreign_key: "follower_id"
has_many :followed, through: :follower
end
基本形が
has_many :(ジョインテーブル名)
has_many :(ジョインの先のテーブル名) through: :(ジョインテーブル名)
だから
要するにこういうことなんだろうなぁと。
has_many :relationships, (class_name: "Relationship",) foreign_key: "follower_id"
has_many :followed, through: :relationships, (source: :followed)
関連記事
Nested Associations and Has_many :through, :source
=> has many throughってこう使うんだよ。的な記事。
[Ruby on Rails] ActiveRecord の歩き方
=> 古い記事。掲載されてるソースコードは実際のとかなり違うので注意。
1から4まである。
Under the hoods of ActiveRecord’s has_many method
=> 三年前の記事
Behind the Scenes of the ‘Has Many’ Active Record Association
=> 日付がないのでいつのかわからないが、Github上の一番新しい奴に近い時点のコードを使ってると思われる。
Author And Source
この問題について(has_many :through のNested Associations), 我々は、より多くの情報をここで見つけました https://qiita.com/TakaakiFuruse/items/ca7b4c681a989eaf32f0著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .