2013-09-17 3 views
1

Я пытаюсь получить массив клиентов, у которых есть как минимум два элемента. Ассоциации довольно просты, но я просто не получаю никаких результатов в своем тесте. Возможно, другой набор глаз может видеть то, что мне не хватает.Rails has_many, habtm SQL join не возвращает никаких результатов

# 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 БД данные):

"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 

ответ

1

Поскольку вы группирование по item_id, вы только получаете одну запись за item_id, так что вы никогда не будете иметь count(item_id) больше, чем один. Вы должны группироваться по people.id.

На соответствующую точку, MySQL является уникальным в том, что:

MySQL расширяет применение GROUP BY так, чтобы выбрать список можно обратиться к неагломерированных столбцов не указанных в GROUP BY п

как задокументировано в http://dev.mysql.com/doc/refman/5.1/en/group-by-extensions.html

+0

Большое вам спасибо за ваш ответ. Вы были абсолютно правы, заявив, что группировка «item_id» неверна, и это открыло мне глаза на проблему. Мне нужно было группировать «order_id». Вы привели меня к проблеме, еще раз спасибо Петру! Если бы я мог, я бы дважды отправил вас в бой. –

+0

Приветствую вас, но если вы группируете 'order_id', я думаю, вы получите людей, которые разместили заказы с более чем двумя элементами, но не получат (например) людей, которые только поместили по два порядка по одному пункту. –

+1

Хорошо, я вижу. Я собирался все время группировать в таблице «items_orders», что не позволило мне группировать «person_id», так как он не существовал. Я изменил предложение группы на 'orders.person_id', и тест прошел отлично. Еще раз спасибо :) –

Смежные вопросы