1

我正在尝试在 Rails 中建立多态关系并且遇到了一些困难。这是我的数据模型:

class Order
    has_many :order_items
end

class OrderItem
    belongs_to :order
end

class PhysicalItem < OrderItem
end

class VirtualItem < OrderItem
end

PhysicalItem 和 VirtualItem 在它们的模型中有足够的差异以保证被拆分到它们自己的表中。所以,我设想有:

订单表

一个物理项目表

一个 virtual_items 表

具有 item_type = ["PhysicalItem" or "VirtualItem"] 和对应表中匹配行的 item_id 的 order_items 表。

我最终希望能够编写这样的代码:

order = Order.new
physical_item = PhysicalItem.new
virtual_item = VirtualItem.new

order.order_items << physical_item
order.order_items << virtual_item

puts order.order_items
# Should list out the physical item and then the virtual item.

理论上看起来很简单,但总体上看来对这种结构的支持并不多。有人对使用 ActiveRecord 在 postgresql 数据库中实现这一点有任何想法吗?

4

2 回答 2

1

你不应该为此需要多态关联。模型中的方法Order也可以工作:

class Order < ActiveRecord::Base
  has_many :physical_items
  has_many :virtual_items

  def order_items
    physical_items + virtual_items
  end
end

class PhysicalItem < ActiveRecord::Base
  belongs_to :order
end

class VirtualItem < ActiveRecord::Base
  belongs_to :order
end

您还需要physical_itemsvirtual_items表都有order_id列。然后,复制您想要的行为:

order = Order.new
physical_item = order.physical_items.new
virtual_item = order.virtual_items.new

puts order.order_items
于 2013-10-28T02:01:57.973 回答
0

您可以将 PostgreSQL HStore 数据类型与 STI 结合使用。通过这种方式,您可以获得在一个表上运行单个表的好处,SELECT但该表不会被类型特定的列污染。

然后,您将只有两个表:

  • 订单表
  • order_items 表

对于 order_items 表,迁移将包括:

class CreateOrderItemsTable < ActiveRecord::Migration
  def change
    create_table :order_items do |t|
      t.integer :order_id
      t.string :type
      t.hstore :data
    end
  end
end

您的模型将如下所示:

class Order
  has_many :order_items
end

class OrderItem
  belongs_to :order
  serialize :data, ActiveRecord::Coders::Hstore
end

class PhysicalItem < OrderItem
end

class VirtualItem < OrderItem
end

我尝试使用多态连接表,但它仍然需要太多的 SQL 查询才能获得关联列表。HStore 与 STI 是一个很好的组合。有关更多信息,请阅读: http: //www.devmynd.com/blog/2013-3-single-table-inheritance-hstore-lovely-combination

于 2013-12-27T18:03:47.783 回答