【问题标题】:Rails has_many, habtm SQL join not returning any resultsRails has_many,habtm SQL join没有返回任何结果
【发布时间】:2013-09-17 16:54:30
【问题描述】:

我正在尝试吸引至少购买了两件商品的客户。关联非常简单,但我在测试中没有得到任何结果。也许另一双眼睛可以看到我错过了什么。

# customer.rb
class Customer < Person
  has_many :orders, foreign_key: 'person_id'
  has_many :items, through: :orders


  # This is what I'm needing help with:
  def self.min_2_orders
    joins(:items).group('items_orders.item_id').having('COUNT(items_orders.item_id) >= ?', 2)
  end
end

-

# order.rb
class Order < ActiveRecord::Base
  belongs_to :customer, foreign_key: 'person_id'
  has_and_belongs_to_many :items
end

-

# item.rb
class Item < ActiveRecord::Base
    has_and_belongs_to_many :orders
end

-

# customer_spec.rb
it "finds customers who have ordered a min of 2 items" do
  @order1, @order2  = FactoryGirl.create_list(:order, 2) #returns 2 created orders

  @order2.items << FactoryGirl.create_list(:item, 2) #returns 2 created items

  @customer1  = @order2.customer
  @customer2  = @order1.customer

  ## Debug tests
    Order.count.should            == 2 #pass
    Customer.count.should         == 2 #pass
    Item.count.should             == 2 #pass
    @order_min.items.count.should == 2 #pass
    @customer1.items.count.should == 2 #pass

    puts Order.all.to_yaml    # debug. see below
    puts Customer.all.to_yaml # debug. see below
    puts Item.all.to_yaml     # debug. see below
  # End debugging

  # The final test
  Customer.min_2_orders.should == [@customer1]  # FAIL. returns []
end

这里是调试日志(sql 查询和 YAML db 数据):

"SELECT 'people'.* FROM 'people'
  INNER JOIN 'orders' ON 'orders'.'person_id' = 'people'.'id'
  INNER JOIN 'items_orders' ON 'items_orders'.'order_id' = 'orders'.'id'
  INNER JOIN 'items' ON 'items'.'id' = 'items_orders'.'item_id'
WHERE 'people'.'type' IN ('Customer')
  GROUP BY items_orders.item_id
  HAVING COUNT(items_orders.item_id) >= 2"

---
- !ruby/object:Order
  attributes:
    id: 1
    person_id: 1
    created_at: 2013-06-18 16:42:17.558683000 Z
    updated_at: 2013-09-17 16:42:17.597082000 Z
- !ruby/object:Order
  attributes:
    id: 2
    person_id: 2
    created_at: 2013-09-17 16:42:17.600267000 Z
    updated_at: 2013-09-17 16:42:17.600267000 Z
---
- !ruby/object:Customer
  attributes:
    id: 1
    first_name: Wes
    type: Customer
    created_at: 2013-09-17 16:42:17.565677000 Z
    updated_at: 2013-09-17 16:42:17.565677000 Z
- !ruby/object:Customer
  attributes:
    id: 2
    first_name: Wes
    type: Customer
    created_at: 2013-09-17 16:42:17.599013000 Z
    updated_at: 2013-09-17 16:42:17.599013000 Z
---
- !ruby/object:Item
  attributes:
    id: 1
    name: Product 1
    created_at: 2013-09-17 16:42:17.632347000 Z
    updated_at: 2013-09-17 16:42:17.632347000 Z
- !ruby/object:Item
  attributes:
    id: 2
    name: Product 2
    created_at: 2013-09-17 16:42:17.633920000 Z
    updated_at: 2013-09-17 16:42:17.633920000 Z

【问题讨论】:

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


    【解决方案1】:

    由于您按item_id 分组,因此每个item_id 只能获得一条记录,因此您的count(item_id) 永远不会大于1。您应该按people.id 分组。

    在相关点上,MySQL 的独特之处在于:

    MySQL 扩展了 GROUP BY 的使用,以便选择列表可以引用 未在 GROUP BY 子句中命名的非聚合列

    http://dev.mysql.com/doc/refman/5.1/en/group-by-extensions.html 中所述

    【讨论】:

    • 非常感谢您的回复。你说item_id 分组是错误的绝对正确,这让我对这个问题大开眼界。我需要按order_id 分组。你把我引向了这个问题,再次感谢彼得!如果可以的话,我会支持你两次。
    • 欢迎您,但如果您按order_id 分组,我想您会得到下订单超过两件的人,但不会(例如)只下两件的人每个订单一件。
    • 好的,我明白了。我一直在考虑在items_orders 表中分组,这不允许我按person_id 分组,因为它不存在。我将 group 子句更改为orders.person_id,测试完美通过。再次感谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 2017-07-07
    • 2017-11-24
    • 1970-01-01
    • 2020-05-10
    相关资源
    最近更新 更多