Basic Table Association

Hello, I’m having the following models:

class Customer < ApplicationRecord
  has_many :orders
  has_many :products, through: :orders
end

class Order < ApplicationRecord
  belongs_to :customer
  has_many :products
end

class Product < ApplicationRecord
  belongs_to :order
end

What is the Rails way to display a full list of all customers, their orders, and the product(s) in each order ? (Unfortunately, I find the Rails documentation not helpful and thus the reason for this post) Thank you!

What kind of difficulty are you facing with that?

If the question is how to display, you need to do it in the erb. I assume that you already have generated a CustomerController / index method as well as an index.erb?

=> Do you want to display all the orders for each customer? if yes you can simply loop through @customer.orders… and then loop through products

Thanks Cedric for your response!

In the CustomerController index action, if I were to select all customers, I can do:

@customer = Customer.all

(And in the erb file, I will render @customer through a for loop to display all customers). This is easy because I’m dealing with one table.

For what I need, if you were to do it the traditional SQL way as you might have dealt with in other languages, you could have done something like this:

SELECT * from customers 
LEFT JOIN orders on customers.order_id = orders.id 
LEFT JOIN products on orders.product_id = products.id

This SQL statement will display all customers, their orders, and the products from each order.

Understanding that Rails uses INNER JOIN instead of LEFT JOIN, that’s fine. That’s not the question.

So back in the CustomerController, how would you select all customers, their orders, and the products in each order so that you can display them in the view ?

Should I do: Customer.joins(:orders, :products) or something like that ? (***)

On the other hand, the given models (Customer, Order, and Product) already show their relationship via key words “has_many” and “belongs_to”,… So that should be enough to already determine a join from three tables and that I may not need to explicitly perform a join statement shown in (***) above. If what I’m saying is confusing, you can ignore and simply show me the way you would do to display all customers, their orders, and the products in each order. I’ll appreciate your assistance. Thanks!

Thanks Cedric for your response.

In the CustomerController index action, if I were to select all customers, I would do:

@customer = Customer.all

and in the corresponding erb file, I’ll render @customer through a for loop to display all customers. This is easy because I’m dealing with one table, so no question here.

For what I need, to display all customers, their orders, and the products from each order, if I were to do it the traditional SQL way as you might have dealt with in other languages, you could do something like this:

SELECT * FROM customers LEFT JOIN orders ON customers.order_id = orders.id LEFT JOIN products ON orders.product_id = products.id

Understanding that Rails uses INNER JOIN instead of LEFT JOIN, that’s fine, that’s not the question.

So, back to the CustomerController, what would you do in order to select all customers, their orders, and the products from each order ?

Should I do: Customer.joins(:orders, :products) which joins three tables the Rails way ? (***)

On the other hand, if you look back at the given models Customer, Order, and Product (feel it to modify them), you should see their associative relationship via key words “has_many” and “belongs_to”. So, in a way, was that enough to ALREADY determine a join of the three tables ? And the explicit join statement shown in (***) above may be redundant ?

If what I’m saying is confusing you, you can ignore. I’ll greatly appreciate if you can show me your way (the Rails way): how would you do in order to display a list of all customers, their orders, and the products from each order ? Thanks a lot !

Thanks Cedric, I eventually figured it out. Thanks.