Rails数据建模 - has_many:through的替代方法,给定多态性?

时间:2010-01-22 22:55:47

标签: ruby-on-rails polymorphism data-modeling

我正在开发一个允许用户将图像与特定事件相关联的应用程序。事件由用户拥有。简单的解决方案当然是:

class Image < ActiveRecord::Base
  belongs_to :event
end

class Event < ActiveRecord::Base
  has_many :images
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :events
  has_many :images, :through => :events
end

除!有一个问题。我还希望我的用户能够直接拥有图像,而无需中间事件。如果我在这里使用“常规”多态关联,那么显然user.images将无法正常工作。我应该抓住我的鼻子,使用:as => :event_images消除歧义,并定义user.all_images是否需要出现?我是否应该让用户直接拥有所有图像,并可选择以某种方式与事件相关联? (当然,还有一个确认一致性的验证......但这似乎有点臭。)是否有第三种解决方案比其中任何一种更漂亮?

1 个答案:

答案 0 :(得分:0)

我经常发现忘记ActiveRecord DSL并在定义复杂关系时直接使用数据模型很有用。一旦数据模型正确,您就可以将其映射到模型语句中。

从您的问题中不清楚图像是否可由用户一个事件拥有,如果它们可以同时归两者所有。该问题将决定您使用的数据模型。

如果两者都拥有图片,则图片表需要同时引用 user_id event_id ,根据您的需要,这可能需要为空用例(用户或事件是可选关系)。如果图片只能由一个拥有,您可以设置某种多态无法使用关系,将所有者映射到正确的所有者表( owner_id owner_type < / strong>等等)。

假设它可以属于两者:

class Image < ActiveRecord::Base
  belongs_to :event
  belongs_to :user
end

class Event < ActiveRecord::Base
  has_many :images
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :events
  has_many :images
  has_many :event_images, :through => :events, :class_name => "Image"
end