Rails:has_many通过多态关联 – 这个工作吗?

一个Person可以有多个Events ,每个Event可以有一个多态的可Eventablelogging。 如何指定PersonEventablelogging之间的关系?

这里是我有的模型:

 class Event < ActiveRecord::Base belongs_to :person belongs_to :eventable, :polymorphic => true end class Meal < ActiveRecord::Base has_one :event, :as => eventable end class Workout < ActiveRecord::Base has_one :event, :as => eventable end 

主要问题涉及Person类:

 class Person < ActiveRecord::Base has_many :events has_many :eventables, :through => :events # is this correct??? end 

我是否说has_many :eventables, :through => :events像上面那样的has_many :eventables, :through => :events

或者我必须像这样拼出来:

 has_many :meals, :through => :events has_many :workouts, :through => :events 

如果你看到一个更简单的方法来完成我所追求的,我就是耳朵! 🙂

你必须做:

 class Person < ActiveRecord::Base has_many :events has_many :meals, :through => :events, :source => :eventable, :source_type => "Meal" has_many :workouts, :through => :events, :source => :eventable, :source_type => "Workout" end 

这将使你能够做到这一点:

 p = Person.find(1) # get a person's meals p.meals.each do |m| puts m end # get a person's workouts p.workouts.each do |w| puts w end # get all types of events for the person p.events.each do |e| puts e.eventable end 

另一个select是使用单表inheritance(STI)或多表inheritance(MTI)模式,但是这需要一些ActiveRecord / DB表返工,但这可能有助于其他人仍然可以find第一次devise它的人。

下面是Rails 3+中的STI方法:你的Eventable概念成为一个类,需要一个type列(这些列会自动为你填充)。

 class Eventable < ActiveRecord::Base has_one :event end 

然后,你的其他两个类inheritance Eventable而不是AR :: Base

 class Meal < Eventable end class Workout < Eventable end 

而你的事件对象基本上是一样的,只是不是多态:

 class Event < ActiveRecord::Base belongs_to :person belongs_to :eventable end 

这可能会使其他一些层次更加混乱,如果你以前从未见过,而且你不小心。 例如,如果您在路由中使两个端点都可用,则可以在/meals/1/eventable/1上访问单个Meal对象,并且您需要知道当您拉取inheritance对象时使用的类(提示:如果您需要重写默认导轨行为,那么becomes 方法可能会非常有用)

但是根据我的经验,这是一个更为清晰的责任划分。 只是一个模式考虑。