2009-11-05 8 views
111

フォーク、ActiveRecord、has_many:through、および多態性の関連付け

これを正しく理解してもらいたいですか?そしてここで継承のためのケース(SentientBeing)を無視して、代わりにhas_many:の多型モデルに焦点を当ててみてください。私が行うとき、しかし

widget.people << my_person 

:それは、完璧な世界では、次の...

class Widget < ActiveRecord::Base 
    has_many :widget_groupings 

    has_many :people, :through => :widget_groupings, :source => :person, :conditions => "widget_groupings.grouper_type = 'Person'" 
    has_many :aliens, :through => :widget_groupings, :source => :alien, :conditions => "video_groupings.grouper_type = 'Alien'" 
end 

class Person < ActiveRecord::Base 
    has_many :widget_groupings, :as => grouper 
    has_many :widgets, :through => :widget_groupings 
end 

class Alien < ActiveRecord::Base 
    has_many :widget_groupings, :as => grouper 
    has_many :widgets, :through => :widget_groupings 
end 

class WidgetGrouping < ActiveRecord::Base 
    belongs_to :widget 
    belongs_to :grouper, :polymorphic => true 
end 

を考えると、私は、ウィジェットと人与えられた、のような何かをしたいと思いますこれは、私は 'grouper'の 'タイプ'が常にwidget_groupingsでnullであることに気づいた。しかし、私は次のようなものに:

widget.widget_groupings << WidgetGrouping.new({:widget => self, :person => my_person}) 

私は通常予想通りに動作します。私はこれが非多態的な関連で起こっているとは思っておらず、これがこのユースケースに特有のものかどうか、あるいはもし私が潜在的にバグを見つめているのかどうかを知りたいと思っていました。

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

答えて

156

known issueには、この機能を無効にするRails 3.1.1があります。この問題を最初に解決している場合は、3.1.2で修正されました

あなたはとても近いです。問題は:sourceオプションを悪用していることです。 :sourceはポリモーフィックなbelongs_to関係を指していなければなりません。次に、定義しようとしている関係のsource_typeを指定するだけです。

ウィジェットモデルに対するこの修正により、探しているものを正確に行うことができます。前述したように

class Widget < ActiveRecord::Base 
    has_many :widget_groupings 

    has_many :people, :through => :widget_groupings, :source => :grouper, :source_type => 'Person' 
    has_many :aliens, :through => :widget_groupings, :source => :grouper, :source_type => 'Alien' 
end 
+0

ああ私の神はとても痛いほど明白だ。感謝EmFi! – Cory

+0

問題はありませんが、私は初めてこれに遭遇したときに、これをどうやって行うのかについて約一日苦労したと思います。私がRailsでやってみた最初のことの1つであるチュートリアル/ブックに従わないことを助けてくれませんでした。 – EmFi

+0

EmFiありがとうございます。 – jdl

-3

多くの:スルーと多型は一緒に機能しません。それらに直接アクセスしようとすると、エラーが発生します。 もし私が間違っていないなら、あなたはwidget.peopleとpushルーチンを書かなければなりません。

私はバグではないと思いますが、これはまだ実装されていないものです。誰もがそれを使用できるケースがあるので、私はこの機能でそれを見ると思います。

+5

彼らは一緒に働くんで修正されています。例: has_many:サブスクリプション、:as:サブスクライブ可能 has_many:サブスクライバ、:through:>:サブスクリプション:source =>:user – ScottJ

+0

失敗コードの例を近くの別の投稿として投げます将来:私はそのエラーを回避する方法を理解する頭痛の多くを保存します。 – cgr

3

、これが原因でバグレール3.1.1で動作しません:ソースが、それはRailsの3.1.2

+0

https://github.com/rails/rails/issues/3271 – EmFi

関連する問題