如何避免多态关联

时间:2010-06-16 05:42:54

标签: ruby-on-rails polymorphic-associations

鉴于你必须实现像社交网络中看到的那样的新闻提要,ex facebook。 目前我正在使用一个具有多态关联的News类,它可以是Image,Comment,Friendship,GroupMembership等任何类型。每当创建一个Object时,也会创建新闻。它与AR(ActiveRecords)一起工作正常,但是当我切换到DM(DataMapper)或Sequel时,我会遇到麻烦,因为它们都不会直接支持多态关联并阻止它的使用。

一种解决方法是使用带有大量UNION的大型SQL子句来合并应被视为新闻的所有不同表。但这有一些缺点,特别是性能会很糟糕。

所以我想知道如何在没有多态关联的情况下解决,同时仍然获得良好的性能而没有其他缺点,例如是否有可能在新闻中添加元数据?

2 个答案:

答案 0 :(得分:22)

免责声明:我是Sequel的首席开发人员。

最好的方法通常取决于您想要对数据做什么类型的事情。一种方法是为所有可能的关系设置外键列:

news:
  id
  ... (Other columns)
  image_id
  comment_id
  friendship_id
  group_membership_id

与使用通用外键和存储类名相比,以这种方式执行操作确实没有性能差异。对于延迟加载,您只需选择一个非nil / NULL的外键字段,然后选择要加载的相应关联。对于每表查询的预先加载,您只需一次加载所有关联。这也更灵活,因为您可以使用JOIN急切加载,这是多态方法无法实现的。此外,您还可以获得真正的参考完整性。

一个缺点是,如果您希望将来添加更多关联类型,则需要向表中添加外键。

答案 1 :(得分:2)

这是一个gem,用于在Rails中维护数据库级别的多态关联的引用完整性:

https://github.com/mkraft/fides

截至发布时,有适用于SQLite3和Postgresql的适配器。

免责声明:我写了宝石。