Ruby on rails Rails中有很多多态性/继承
我试图在Rails中建立多态关系,但遇到了一些困难。以下是我的数据模型:Ruby on rails Rails中有很多多态性/继承,ruby-on-rails,inheritance,activerecord,polymorphism,rails-postgresql,Ruby On Rails,Inheritance,Activerecord,Polymorphism,Rails Postgresql,我试图在Rails中建立多态关系,但遇到了一些困难。以下是我的数据模型: class Order has_many :order_items end class OrderItem belongs_to :order end class PhysicalItem < OrderItem end class VirtualItem < OrderItem end 类顺序 有很多:订购物品 结束 类OrderItem 属于:秩序 结束 类PhysicalItem
class Order
has_many :order_items
end
class OrderItem
belongs_to :order
end
class PhysicalItem < OrderItem
end
class VirtualItem < OrderItem
end
类顺序
有很多:订购物品
结束
类OrderItem
属于:秩序
结束
类PhysicalItem
PhysicalItem和VirtualItem在其模型中有足够的差异,足以保证将其拆分到各自的表中。因此,我设想:
点菜台
物理项目表
虚拟项目表
order_items表,其item_type=[“PhysicalItem”或“VirtualItem”]和对应表中匹配行的item_id
我最终希望能够编写如下代码:
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.
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
order=order.new
物理项=PhysicalItem.new
虚拟项=VirtualItem.new
order.order\u items您不应该为此需要多态关联。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
您不应该为此需要多态关联。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
您可以将PostgreSQL HStore数据类型与STI结合使用。通过这种方式,您可以在一个表上运行单个SELECT
,但该表不会被特定类型的列污染
然后,您将只有两个表:
- 订单表
- 订单项目表
对于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 CreateOrderItemsTable
然后,您的模型将如下所示:
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.
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
类顺序
有很多:订购物品
结束
类OrderItem
属于:秩序
序列化:数据,ActiveRecord::Coders::Hstore
结束
类PhysicalItem
我尝试使用多态联接表,但它仍然需要太多SQL要求才能获得关联列表。HStore与STI是一个很好的组合。有关更多信息,请阅读以下内容:您可以将PostgreSQL HStore数据类型与STI结合使用。通过这种方式,您可以在一个表上运行单个SELECT
,但该表不会被特定类型的列污染
然后,您将只有两个表:
- 订单表
- 订单项目表
对于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 CreateOrderItemsTable
然后,您的模型将如下所示:
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.
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
类顺序
有很多:订购物品
结束
类OrderItem
属于:秩序
序列化:数据,ActiveRecord::Coders::Hstore
结束
类PhysicalItem
我尝试使用多态联接表,但它仍然需要太多SQL要求才能获得关联列表。HStore与STI是一个很好的组合。有关更多信息,请阅读以下内容:当PhysicalItem
和VirtualItem
继承自产品时,我在您的列表中没有看到产品型号?它在哪里适合所有这些?我想我真的不需要产品模型-我从中得到的唯一东西是能够查询order.products,然后检索大量混合物理项和虚拟项。此外,我编辑了我的问题来反映我更新的对象名称-抱歉之前的混乱。如果你使用不同的表考虑使用一个使MTI更容易的宝石。当<代码>物理项< /代码>和<代码> ViualItIs<代码>从产品继承时,我在你的列表中没有看到一个产品模型吗?它在哪里适合所有这些?我想我真的不需要产品模型-我从中得到的唯一东西是能够查询order.products,然后检索大量混合物理项和虚拟项。此外,我编辑了我的问题来反映我更新的对象名称-抱歉之前的混乱。如果你使用不同的表考虑使用一个宝石,使MTI更容易。当然,但让我们说,有人增加了30个不同的项目到他们的购物车。我想选择他们添加的前10个项目——如果不查询所有项目,按照创建的时间戳对最终列表进行排序,然后扔掉其他模型,我就无法做到这一点。这将是一个非常缓慢的操作。当然,但假设有人在购物车中添加了30种不同的物品。我想选择他们添加的前10个项目——如果不查询所有项目,按照创建的时间戳对最终列表进行排序,然后扔掉其他模型,我就无法做到这一点。这将是一个非常缓慢的操作。