fall
fall

Reputation: 3

Order, Product and OrdersProduct models associations

I am building a rails app in where I need to have Product and Order models.

I think the logical path is to have another model, called OrdersProduct, since a Order can have many products to be ordered, in which I put a product_id, order_id (matching the two other models) and an amount field.

Well, my problem is how can I access each single product information from my OrdersProduct record?

The point is I can do a belongs_to :product association into my OrdersProduct model, but it doesn't makes any sense to put a has_many :orders_products in my Product model.

Models seems something like this:

class Customer < ActiveRecord::Base
  # id
  # name
  # etc…
end

class Product < ActiveRecord::Base
  # id
  # name
  # etc…
end

class Order < ActiveRecord::Base
  # id
  # customer_id
  # etc…
end

class OrdersProduct < ActiveRecord::Base
  # order_id
  # product_id
  # amount
end

What's the best way to have access to Order.products and get a collection of products related to the OrdersProduct model?

Upvotes: 0

Views: 1931

Answers (2)

Jozef Vaclavik
Jozef Vaclavik

Reputation: 549

What you want is to use Has and belongs to many through association.

class Order < ActiveRecord::Base
  has_many :orders_products
  has_many :products, through: :orders_products
end

class Product < ActiveRecord::Base
  has_many :orders_products
  has_many :orders, through: :orders_products
end

class OrdersProduct < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
end

Now in commerce terminology, ordered products are often referenced as LineItem so instead of using orders_products table you could specify line_items table.

class Order < ActiveRecord::Base
  has_many :line_items
  has_many :products, through: :line_items
end

class Product < ActiveRecord::Base
  has_many :line_items
  has_many :orders, through: :line_items
end

class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
end

Upvotes: 2

neo
neo

Reputation: 4116

You can get rid of the OrdersProduct model.

Just need the following models:

class Customer < ActiveRecord::Base
  has_many :orders
  # id
  # name
  # etc…
end

class Order < ActiveRecord::Base
  belongs_to :customer
  has_many :products

  # id
  # customer_id
  # etc…
end

class Product < ActiveRecord::Base
  belongs_to :order

  # id
  # name
  # order_id
  # etc…
end

So now you can call customer.orders.first.products or order.products given that customer and order are instances.

Upvotes: -1

Related Questions