Rails3で has_many through でしかも polymorphic な関連を実装していて、polymorphicなモデル側からhas_manyを探せるけど、逆のやり方に苦戦したのでメモ
User モデルは複数の Clubに属すことができて、Clubもまた複数の Userを受け入れられるという感じ。
最初にやってた方法
Membership はpolymorphicなモデルにしていて、例えばClub以外にもFamilyとか他のグループでも同じモデルを使いまわしたかった。
データを作ってみる
rails consoleでデータを作成
user = User.create({ name: 'kozo' }) => #<User id: 1, name: "kozo", created_at: "2013-06-14 03:14:59", updated_at: "2013-06-14 03:14:59"> club = Club.create({ name: 'football' }) => #<Club id: 1, name: "football", created_at: "2013-06-14 03:14:50", updated_at: "2013-06-14 03:14:50"> club.memberships.create({ user_id: user.id }) => #<Membership id: 1, user_id: 1, membable_id: 1, membable_type: "Club", created_at: "2013-06-14 03:15:19", updated_at: "2013-06-14 03:15:19">
Club -> Userの参照はうまくいく
こんな感じにClub側からUserを参照するのは簡単にできちゃう
club = Club.find(1) club.members # =>[#<User id: 1, name: "kozo", created_at: "2013-06-14 03:14:59", updated_at: "2013-06-14 03:14:59">]
User -> Clubの参照はできなかった・・・
user = User.find(1) user.membered_clubs # => ActiveRecord::HasManyThroughSourceAssociationNotFoundError: Could not find the source association(s) :membable in model Membership. Try 'has_many :membered_clubs, :through => :memberships, :source => <name>'. Is it one of :user or :club?
ドキュメントにはsourceとsource_typeを使えばOKって書いてあるっぽい
ruby/rails/RailsGuidesをゆっくり和訳してみたよ/Active Record Associations - 株式会社ウサギィwiki
4.3.2.18 :source
:source オプションは has_many :through アソシエーションの元になるアソシエーション名を指定します。 元のアソシエーションの名前が自動的にアソシエーション名から推測できない場合にのみ、このオプションを使用する必要があります。
4.3.2.19 :source_type
:source_type オプションは polymorphic アソシエーションを通じて進める has_many :through アソシエーションの元になる型を指定します。
でもググったらすぐ出てきた
has_many :through - The other side of polymorphic :through associations
MembershipとUserに細かく書いてあげるといいっぽい
club = Club.find(1) => #<Club id: 1, name: "football", created_at: "2013-06-14 03:14:50", updated_at: "2013-06-14 03:14:50"> club.members => [#<User id: 1, name: "kozo", created_at: "2013-06-14 03:14:59", updated_at: "2013-06-14 03:14:59">] user = User.find(1) => #<User id: 1, name: "kozo", created_at: "2013-06-14 03:14:59", updated_at: "2013-06-14 03:14:59"> user.membered_clubs => [#<Club id: 1, name: "football", created_at: "2013-06-14 03:14:50", updated_at: "2013-06-14 03:14:50">]
できた!
0 コメント:
コメントを投稿