1. ホーム
  2. ruby-on-rails

[解決済み] ActiveRecord、has_many :through, そしてポリモーフィックアソシエーション

2022-05-14 19:01:48

質問

皆さん。

私がこれを正しく理解していることを確認したいと思います。そして、ここ(SentientBeing)での継承のケースは無視し、代わりにhas_many :through 関係のポリモーフィックモデルに焦点を当てようとしてください。とはいえ、次のように考えてみてください...

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

完璧な世界では、WidgetとPersonが与えられたら、次のようなことをしたい。

widget.people << my_person

しかし、これを実行すると、widget_groupingsの中で、「グルーパー」の「タイプ」が常にnullになっていることに気づきました。しかし、私は次のようなものにすると。

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

そして、すべてが私が通常期待するように動作します。多形でない関連付けでこれが発生するのを見たことがないので、これがこの使用ケースに特有のものであるかどうか、または私が潜在的にバグを見つめているのかどうかを知りたかっただけなのです。

どんな助けでもありがとうございます!

どのように解決するのですか?

には 既知の問題 があり、この機能はRails 3.1.1では壊れます。この問題がある場合、まずアップグレードを試してみてください。

あと少しです。問題は :source オプションの使い方を間違えていることです。 :source はポリモーフィックな belongs_to 関係を指すはずです。そうすると、定義しようとしている関係に対して :source_type を指定すればいいだけです。

Widgetモデルへのこの修正により、あなたが探しているものを正確に行うことができるようになるはずです。

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