【问题标题】:Rails 3 merging similar instances in a has_many relationshipRails 3在has_many关系中合并相似的实例
【发布时间】:2011-08-31 03:44:04
【问题描述】:

我有两个模型。订单和line_item。

class Order < ActiveRecord::Base  
    has_many :line_items
    has_many :products, :through => :line_items
end

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

line_items 包括以下属性 - :product_id:size:quantity

对于相同的产品和尺寸,一个订单可能有多个 line_item,在这种情况下,我希望能够访问合并为一个的 line_items,其数量是所有这些的总和。例如,一个订单可能有以下 line_items:

# | product_id | size   | quantity
1 | 1          | small  | 1
2 | 1          | small  | 2
3 | 1          | medium | 1
4 | 2          | small  | 1

应该合并到:

# | product_id | size   | quantity
1 | 1          | small  | 3
2 | 1          | medium | 1
3 | 2          | small  | 1

在我看来,这应该是订单模型上的范围或类方法,所以我可以从视图中调用@order.line_items_merged 或类似的东西,但我不太确定如何实现它。有人可以帮忙吗?

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    为同一个(产品、尺寸)对设置多个订单项真的有意义吗?你真的会单独使用它们,还是只合并使用它们?

    我个人会考虑更改逻辑,以便您不能为同一产品和尺寸拥有多个订单项(即直接增加数量,而不是创建多条记录进行合并),并且从而避免这个问题!

    【讨论】:

    • 按照您提到的方式进行操作感觉不舒服,因为这意味着如果 line_item 在用户尝试创建它。
    • 我会在 Order 模型中添加一个 add_product 方法,然后从您的控制器中调用它。
    • 我想这就是我要做的,尽管我仍然很想看到对所提出问题的直接解决方案 - 纯粹是一种心理锻炼!
    • 在 Rails 3 中你可以使用LineItem.group(:product_id, :size).sum(:quantity),它会返回一个哈希{[1, "small"] =&gt; 3, [1, "medium"] =&gt; 1, [2, "small"] =&gt; 1}。不过,我认为没有一种直接的方法可以返回 LineItem 的实例,因为它们与数据库中的记录不对应,因此这样做没有任何意义。
    【解决方案2】:

    好的,为什么要将line_items 组合成一个虚拟实体?

    对我来说似乎更容易在 Order 类中创建方法/范围,该类遍历 line_items 并获取需要的数据。再次不确定您的最终目标是什么。

    Order类:

    def qty
      line_items.map{|li| li.quantity}.sum
    end
    
    def sizes
      line_items.map{|li| li.size}.uniq
    end
    

    如果订单已经加载到内存中的非常简单的示例-希望对您有所帮助。 如果需要数据库搜索/排序,那么您可以在 lib 目录中定义一个 line_items 模块,并直接从复数 line_items 调用中调用方法......对于“订单”也可以这样做

    所以extend你的模型关联声明:

    has_many :line_items, :extend => LineItemsMethods, :dependent => :destroy
    

    LineItemsMethods类:

    def any_special_products?
      any? {|line_item| line_item.special_method}   
    end
    

    Scopes 当然也可以工作...尽量保持简单,希望对您有所帮助。


    编辑

    我完全错过了您示例的第二行,其中一个 line_item 的数量已经为 2。所以我同意第一个答案:如果您要让用户输入数量,那么可以选择相同的产品再次;它应该只更新现有数量,无论它是否已保存...

    【讨论】:

    • 如果您只是想显示 line_items(您提到的视图),那完全是另外一回事......
    • 从头开始更改和重写您的整个答案并不是一个好习惯。如果您认为您的答案在某种程度上变得毫无意义,请投票删除它。如果它仍然有一些信息,即使是被证明是错误的信息,只需用正确的信息更新它,而不会丢失整个原始答案。
    猜你喜欢
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多