2014-01-02 5 views
0

У меня есть тест приложение с моделями следующимRoR ActiveRecord Запрос производит неожиданный результат

ActiveRecord::Schema.define(version: 20140102023300) do 

    create_table "customers", force: true do |t| 
    t.string "name" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "order_products", force: true do |t| 
    t.integer "customer_id" 
    t.integer "order_id" 
    t.integer "product_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "orders", force: true do |t| 
    t.text  "description" 
    t.integer "customer_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "products", force: true do |t| 
    t.string "description" 
    t.float "item_price" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

end 

Ассоциацией является

class Customer < ActiveRecord::Base 
    has_many :orders 
end 

class Order < ActiveRecord::Base 
    belongs_to :customer 
    has_many :order_products 
end 

class OrderProduct < ActiveRecord::Base 
    belongs_to :order 
end 

Затем я посеянная базы данных с seeds.rb следующим образом:

customers = Customer.create([{:name => 'Alex'}, {:name => 'Clare'}, {:name => 'Bob'}, {:name => 'Ian'}]) 

orders = Order.create([ 
    {:description => 'description for order 1',:customer_id => 1}, 
    {:description => 'description for order 2',:customer_id => 2}, 
    {:description => 'description for order 3',:customer_id => 2}, 
    {:description => 'description for order 4',:customer_id => 1}, 
    {:description => 'description for order 5',:customer_id => 4} 
    ]) 

orderproducts = OrderProduct.create([ 
    {:customer_id => 1, :order_id => 1, :product_id => 1}, 
    {:customer_id => 1, :order_id => 1, :product_id => 2}, 
    {:customer_id => 1, :order_id => 2, :product_id => 4}, 
    {:customer_id => 1, :order_id => 2, :product_id => 7}, 
    {:customer_id => 1, :order_id => 2, :product_id => 3}, 
    {:customer_id => 2, :order_id => 1, :product_id => 5}, 
    {:customer_id => 2, :order_id => 1, :product_id => 6}, 
    {:customer_id => 2, :order_id => 2, :product_id => 3}, 
    {:customer_id => 2, :order_id => 2, :product_id => 4}, 
    ]) 

products = Product.create([ 
    {:description => 'teddy bear', :item_price => 19.95}, 
    {:description => 'doll', :item_price => 24.00}, 
    {:description => 'lego', :item_price => 16.00}, 
    {:description => 'toy truck', :item_price => 29.95}, 
    {:description => 'crayons pk10', :item_price => 17.90}, 
    {:description => 'sketch pad', :item_price => 21.50}, 
    {:description => 'football', :item_price => 10.55}, 
    ]) 

Затем в Rails консоли я загружая переменную со списком клиентов:

@customers = Customer.all 

Когда я запускаю эту команду: @customers.find(1).orders я правильно получить

Order id: 1, description: "description for order 1", customer_id: 1, created_at: "2014-01-02 02:51:36", updated_at: "2014-01-02 02:51:36">, 

Order id: 4, description: "description for order 4", customer_id: 1, created_at: "2014-01-02 02:51:36", updated_at: "2014-01-02 02:51:36">] 

Затем я хочу, чтобы запросить элементы внутри каждого заказа. Для простоты скажем Я хочу найти продукты в заказе 1, для клиента 1.

Я попробовал этот запрос: @customers.find(1).orders.find(1).order_products, но я получаю этот результат:

OrderProduct id: 1, customer_id: 1, order_id: 1, product_id: 1, created_at: "2014-01-02 02:51:36", updated_at: "2014-01-02 02:51:36">, 

OrderProduct id: 2, customer_id: 1, order_id: 1, product_id: 2, created_at: "2014-01-02 02:51:36", updated_at: "2014-01-02 02:51:36">, 

OrderProduct id: 6, customer_id: 2, order_id: 1, product_id: 5, created_at: "2014-01-02 02:51:36", updated_at: "2014-01-02 02:51:36">, 

OrderProduct id: 7, customer_id: 2, order_id: 1, product_id: 6, created_at: "2014-01-02 02:51:36", updated_at: "2014-01-02 02:51:36"> 

Похоже, он возвращает результаты для orders.find(1).order_products части запроса, так как все результаты order_id: 1. Проблема состоит в том, что этот набор результатов включает результаты для customer_id: 1 и 2.

То, что я действительно хочу видеть, это продукты в пределах order 1, для customer 1. Можете ли вы помочь мне понять правильный запрос, который мне нужен?

+0

Похоже, что у вас есть некоторые проблемы с данными вашего семени. Я разместил решение, которое предлагает 1) исправление как есть, и 2) способ исправить семенные данные, чтобы ваш исходный запрос работал. – zeantsoi

ответ

1

Ваш запрос в основном возвращается весь список из OrderProduct, которые принадлежат к Order - пути вы структурированном запрос, это в основном агностик к UserOrder принадлежат. Например, согласно вашей схеме - заказчик № 1 имеет заказ №1, но заказ № 1 также принадлежит заказчику № 2. Поскольку запрос относится к заказам, принадлежащим заказу, заказ № 1 будет возвращать записи для клиента № 1 и заказчика №2.

Поскольку OrderProduct имеет внешние ключи как Customer и Order, вы можете попробовать более явный запрос для получения продуктов порядка, которые принадлежат к конкретным клиенту и заказа:

OrderProduct.where(:customer_id => 1, :order_id => 1) 

UPDATE :

У вас есть некоторые проблемы в вашем seeds.rb, которые приводят к запутанным отношениям. Вы определили, что Order принадлежит Customer, но семя базы данных предполагает, что заказы принадлежат многочисленным клиентам.

orderproducts = OrderProduct.create([ 
    {:customer_id => 1, :order_id => 1, :product_id => 1}, 
    {:customer_id => 1, :order_id => 1, :product_id => 2}, 
    {:customer_id => 1, :order_id => 2, :product_id => 4}, 
    {:customer_id => 1, :order_id => 2, :product_id => 7}, 
    {:customer_id => 1, :order_id => 2, :product_id => 3}, 
    {:customer_id => 2, :order_id => 1, :product_id => 5}, # Order 1 already belongs to Customer 1 
    {:customer_id => 2, :order_id => 1, :product_id => 6}, # Order 1 already belongs to Customer 1 
    {:customer_id => 2, :order_id => 2, :product_id => 3}, # Order 2 already belongs to Customer 1 
    {:customer_id => 2, :order_id => 2, :product_id => 4}, # Order 2 already belongs to Customer 1 
    ]) 

После того, как вы убедитесь, что каждый заказ связан с одного клиента, вы можете оформить свой первоначальный запрос для получения продуктов заказа, принадлежащие к заказу пользователя:

@customers.find(1).orders.find(1).order_products 
#=> OrderProduct id: 1, customer_id: 1, order_id: 1, product_id: 1, created_at: "2014-01-02 02:51:36", updated_at: "2014-01-02 02:51:36">, 
#=> OrderProduct id: 2, customer_id: 1, order_id: 1, product_id: 2, created_at: "2014-01-02 02:51:36", updated_at: "2014-01-02 02:51:36">, 
+0

Блестящий zeantsoi !! Я всегда очень благодарен за руководство экспертов. Огромное спасибо. :-) – AxleMax

+0

Zeantsoi, могу я задать еще один вопрос, пожалуйста? Удалил бы client_id из схемы модели OrderProcuct? (и соответствующие данные семени) – AxleMax

+0

Примечание для других рубиновых Noobies, таких как я: @ customers.find (1) .orders.find (1) .order_products возвращает товары для этого заказа, но @ customers.find (1) .orders .find (2) .order_products терпит неудачу, потому что следующий order_id для этого клиента равен 4. Так работает @ customers.find (1) .orders.find (4) .order_products. Если вы хотите перечислить/повторить заказы для клиента, используйте @ customers.find (1) .orders [0] для доступа к массиву (ActiveRecord :: Associations :: CollectionProxy: object) – AxleMax

0

If вы знаете, что customer_id и order_id, вы можете запросить OrderProduct как таковой

OrderProduct.where(customer_id: 1, order_id: 1) 

Однако вы можете также использовать активные записи ассоциации, чтобы иметь что-то вроде

Customer.find(1).orders.first.order_products # to get all order_products of the first order of the customer. 

ИЛИ

Customer.find(1).where(order_id: 1).order_products 

Обратитесь к этому отличное руководство от the docs

+0

Вау ... первая часть вашего ответа выглядит странно знакомой. Но вторая часть просто перефразирует код из вопроса OP - и это не сработает. Связь между Заказчиком и Ордером - это много-ко-многим, поэтому запрос, который вы предложили (т. Е. Перефразированный из вопроса), может возвращать товары заказа, принадлежащие _more, чем один пользователь_. – zeantsoi

+0

Я ценю ответ на этот вопрос. Я нахожу это очень полезным. В ответ на комментарий zeantsoi, я проверил вторую часть этого ответа, и это не работает для меня. – AxleMax

+0

@zeantsoi - :) .. Я видел ваше сообщение после того, как я разместил свой. Но ты избил меня. По заказу клиента, как вы видите много-много? «Заказ» связан с одним клиентом, нет? По крайней мере, схема подсказывает это. –

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