Rails 3.0 - 最佳实践:模型对象的多个子类型

时间:2011-05-18 12:43:40

标签: ruby-on-rails inheritance

所以这可能是一个相当容易回答的问题,但无论如何都要进行。

我想拥有这个视图,比如media_objects /,它显示了一个媒体对象列表。够容易吧?但是,我希望媒体对象列表是MediaObject,CDMediaObject,DVDMediaObject等子类型的集合。这些子类型中的每一个都需要使用db表来表示特定的元数据集,这些元数据在子类型中并不完全相同。

我的第一个传递是为每个子类型创建一个模型,将MediaObject变得足够聪明,以便在其概念性的“所有”行为上加入这些表。这看起来很简单,但我最终做了许多小东西,感觉不是那么棒,所以我想在这里寻求建议。

显然,我没有这个例子的具体代码,但如果你有疑问,我很乐意编辑这个问题来提供这些信息......

谢谢!

3 个答案:

答案 0 :(得分:7)

为每个子类型创建模型是可行的方法,但您所讨论的是多表继承。 Rails假定单表继承,并提供非常简单的设置支持。在type表中添加media_objects列,并将每个特定类型的MediaObject的所有列添加到表中。然后将每个模型设为MediaObject的子类:

class MediaObject < ActiveRecord::Base

end

class CDMediaObject < MediaObject

end

Rails将处理拉出记录并实例化正确的子类,这样当你MediaObject.find(:all)时,结果将包含MediaObject的各个子类的实例的混合。

请注意,这不符合您的要求:

  

这些子类型中的每一个都需要使用db表来表示特定的元数据集,这些元数据在子类型中并不完全相同。

Rails是关于约定优于配置的,如果你编写应用程序的优势而不是期望Rails能够适应你的需求,它将使你的生活变得非常轻松。是的,STI将浪费空间,为每条记录留下一些未填充的列。你应该关心吗?可能不是;数据库存储很便宜,如果重要的列上有索引,额外的列不会影响查找性能。

也就是说,您可以将something very close设置为多表继承,但您可能不应该这样做。

答案 1 :(得分:0)

我想说,这取决于您的数据:例如,如果特定媒体对象之间的差异不必搜索,您可以使用带有TEXT列的单个db表,例如“additional_attributes”。使用rails,您可以将任意数据序列化到该列中。

如果你不能使用它,你可以有一个通用表“media_objects”,其中“有一个:数据集”。在数据集中,您可以在CDMediaObject,DVDMediaObject等之间存储细节

完全不同的方法是使用MongoDB(而不是MySQL),这是一个文档存储。每个文档都可以有完全不同的形式。整个文档树也可以搜索。

答案 2 :(得分:0)

我知道这个问题已经很老了,但只是放下我的想法,如果有人来到这里。

如果数据库是postgres,我建议在hstore列中使用STI来存储不同对象之间不常见的属性。这样可以避免在DB中浪费空间,但可以访问不同操作的属性。

相关问题