【问题标题】:How do I handle using 1 model to belong_to 2 different models at different times?如何在不同时间使用 1 个模型来属于 2 个不同的模型?
【发布时间】:2013-06-17 17:52:11
【问题描述】:

我正在创建一个购物车。

所以我将有一个名为 LineItem 的模型。

每个购物车实例都有 1+ 个订单项。完成的交易也将成为“订单”。

因此,理论上,LineItem belongs_to Cart 和 belongs_to Order。

但是,数据库表会是什么样子? cart_idorder_id 在我的 LineItems 表中?

这意味着对于每条有效的购物车记录,都会有一个 order_id 为 nil(或为空)。同样,对于每个有效订单,都会有一个空的cart_id

这似乎是一种非 Railsy 方式。

最好的方法是什么?多态关联?如果我应该这样做会是什么样子?

【问题讨论】:

  • 你应该考虑一下 LineItem - Cart/Order 是否真的是一对多的关系。我认为这是多对多,所以首先你应该考虑 has_many through 或 has_and_belongs_to_many 关系。
  • 一对多。 1 个购物车有许多 LineItems。 1 LineItem 不能属于多个购物车。但是,1 个 LineItem 可以属于一个购物车 + 一个订单。

标签: ruby-on-rails ruby-on-rails-3 associations


【解决方案1】:

订单项模型可以有两个 belongs_to 关联

class LineItem < ActiveRecord::Base
    belongs_to :cart
    belongs_to :order
end

但是如果它需要属于几个不同的类,这可能会变得混乱。解决方案是多态关联,它允许一个模型在一个单一关联上属于多个模型,在下面的示例中是:line_itemable。它将向 LineItem 模型添加两个属性,line_itemable_idline_itemable_type

class LineItem < ActiveRecord::Base
    belongs_to :line_itemable, :polymorphic => true
end

class Order < ActiveRecord::Base
    has_many :line_items, :as => :line_itemable
end

class Cart < ActiveRecord::Base
    has_many :line_items, :as => :line_itemable
end

如果购物车和订单具有相似的属性(例如成本),那么另一种选择是消除订单类并在购物车上简单地添加 :paid 标志。

【讨论】:

  • 所以我只会写rails g model LineItem,而不是rails g model LineItemable
  • 另外...我应该运行哪些迁移?
  • LineItem 是模型的名称,line_itemable 是关联的名称。所以rails g model LineItem line_itemable_id:integer line_itemable_type:string
  • 顺便说一句....在我的CartOrder 模型中,我要添加什么外键?只是line_item_id?还是什么都没有?
  • 声明 has_many :line_items, :as =&gt; :line_itemable 就足够了
【解决方案2】:

我建议多态关联。

class LineItem < ActiveRecord::Base
  belongs_to :owner, :polymorphic => true
end



class Order < ActiveRecord::Base
  has_many :line_items, :as => :owner
end



class Cart < ActiveRecord::Base
  has_many :line_items, :as => :owner
end

您需要将 owner_type 和 owner_id 添加到 line_items 表中。

参考this

【讨论】:

  • 这是一个好的开始,但有点令人困惑。我更喜欢@omarshammas 的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-29
  • 1970-01-01
  • 2014-03-23
  • 1970-01-01
  • 2021-06-20
相关资源
最近更新 更多