Rails:has_many通过多态关联 – 这个工作吗?
一个Person
可以有多个Events
,每个Event
可以有一个多态的可Eventable
logging。 如何指定Person
和Eventable
logging之间的关系?
这里是我有的模型:
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
方法可能会非常有用)
但是根据我的经验,这是一个更为清晰的责任划分。 只是一个模式考虑。