Rails 3:为什么要复制具有多个关联记录的记录?

时间:2013-10-24 22:30:08

标签: mysql ruby-on-rails ruby

社团:

  • 发货有很多发票
  • 发票属于货件

我得到这样的货件清单......

@shipments = Shipment.joins(:invoices).where(:customer_id => @customer.id).where("customer_open_balance <> 0").where("bill_to IS NULL").order("file_number ASC") 

然后我像这样扁平化......

@invoices = @shipments.map(&:invoices).flatten

我得到重复。例如,我在此行上方进行货运查询,@shipments.count我得到5个结果。

然后在我压扁之后,如果有一个发货有两张发票,它会复制它们而我得到4而不是两个@invoices.count我得到7(应该仍然是5)。

2 个答案:

答案 0 :(得分:1)

使用joins时,返回的记录可能是重复的。因此,如果Tree有多个leaves,那么Tree.joins(:leaves).count将等于叶数和许多重复记录tree。这是因为joins正在调用sql&#39; s INNER JOIN,它返回两个表的交集。

来自Rails guide

  

Category.joins(:帖)

     

或者,用英语:“为所有类别返回一个Category对象   上岗”。请注意,如果有多个类别,您将看到重复的类别   帖子有相同的类别。如果您想要独特的类别,可以使用   Category.joins(:柱)。选择(“不同(categories.id)”)

所以对你来说这样的事情会起作用:

@shipments = Shipment.joins(:invoices).where(:customer_id => @customer.id).where("customer_open_balance <> 0").where("bill_to IS NULL").order("file_number ASC").
             select("distinct(shipments.id)")

另一种方法是使用group

@shipments = Shipment.joins(:invoices).where(:customer_id => @customer.id).where("customer_open_balance <> 0").where("bill_to IS NULL").order("file_number ASC").
             group("shipments.id")

我更喜欢group,因为当与其他范围链接时,Rails中的select语句有时会被忽略。

PS:如果您的查询在invoices上没有任何条件,请尝试使用includes代替joins。这将eagerload一个查询的所有发票,而不是为每个shipment单独查询。

答案 1 :(得分:0)

尝试将.uniq添加到初始查询中:

@shipments = Shipment.uniq.joins(:invoices).where(:customer_id => @customer.id).where("customer_open_balance <> 0").where("bill_to IS NULL").order("file_number ASC")
相关问题