has_many和单表继承

时间:2009-05-20 17:37:30

标签: ruby-on-rails has-many single-table-inheritance

我在两个实体之间有一个has_many关系,Feeds和Posts。我还有特定类型的帖子,视频和照片。这是使用单表继承在数据库中构建的。

现在我的Feed模型指定了Feed和帖子之间的has_many关系(包括子类型)

class Feed < ActiveRecord::Base
  has_many :posts
  has_many :photos
  has_many :videos

是否有更好,更传统的方式来指定它?或者是我能拥有的那么简单?

3 个答案:

答案 0 :(得分:5)

如果我理解正确,你有帖子和帖子可以是视频或照片。正如Jaryl所说,你所拥有的东西可能是最容易理解/处理的,但如果你想得到想象,你可以使用单表继承或多态关联。

STI - 示例(来自使用Rails第3版的Agile Web开发)

create_table :people, :force => true do |t|
   t.string :type

   #common attributes
   t.string :name
   t.string :email

   #attributes for type=Customer
   t.decimal :balance, :precision => 10, :scale => 2

   #attributes for type=Employee
   t.integer :reports_to
   t.integer :dept

   #attributes for type=Manager
   #none
end

class Person < ActiveRecord::Base
end

class Customer < Person
end

class Employee < Person
   belongs_to :boss, :class_name => "Manager", :foreign_key => :reports_to
end

class Manager < Person
end

因此,如果您创建了一个客户

Customer.create(:name => 'John Doe', :email => 'john@doe.com', :balance => 78.29)

然后你可以通过人

找到它
x = Person.find_by_name('John Doe')
x.class #=> Customer
x.email #=> john@doe.com
x.balance #=> 78.29
x.some_customer_class_method # will work because the Person.find method returned a Customer object

所以你可以拥有

class Post < ActiveRecord::Base
end
class Photo < Post
end
class Video < Post
end

然后你可以通过Post.all找到它们,但是你会得到照片和视频对象(如果你的帖子不是照片或视频,也可以发布对象)

不要忘记字符串:在数据库表中键入

答案 1 :(得分:2)

这是你能做的最简单的事情。

好吧,如果照片可以和视频一样对待,那么也许您可以取消STI并使用命名范围来提供不同类型内容的访问者。

答案 2 :(得分:0)

我同意问题中的例子很简单。它已经在使用STI并明确说明了这些关联。

此外,您可以稍后删除STI,并将照片和:视频拆分到各自的单独表格中,而无需更改Feed模型的代码。得分!