Question

I have a Category, a Subcategory and a Product model.

I have:

Category has_many Subcategories
Subcategory has_many Products
Subcategory belongs_to Category
Product belongs_to Subcategory

Is there a way to have something like

Category has_many Projects through Subcategories

?

The 'normal' rails way wouldn't work because "subcategory" doesn't belongs to product so product does not have a subcategory_id field. Instead, I need the query to be something like

SELECT * FROM products WHERE id IN category.subcategory_ids

Is there a way to do that?

Thanks,

Nicolás Hock Isaza

Was it helpful?

Solution

If you do this the 'normal' Ruby on Rails way, the database you described would look something like this. If your database isn't structured like this, I suggest reading more about how associations are done for in Ruby on Rails because this is the right way (and you should be using t.references :category in your migration since it was designed to make it easy to not mess your references up).

+----------------+  +----------------+ +----------------+
| categories     |  | subcategories  | | products       |
+----------------+  +----------------+ +----------------+
| id             |  | id             | | id             |
| ...            |  | category_id    | | subcategory_id |
|                |  | ...            | | ...            |
+----------------+  +----------------+ +----------------+

With this as your database structure, the has_many :products, :through => subcategories works for the Category model.

Category.rb
class Category < ActiveRecord::Base
  has_many :subcategories
  has_many :products, :through => :subcategories
end
Subcategory.rb
class Subcategory < ActiveRecord::Base
  belongs_to :category
  has_many :products
end
Product.rb
class Product < ActiveRecord::Base
  belongs_to :subcategory
  has_one :category, :through => :subcategory  # don't need this, but it does work
end
ruby script\console
>> c = Category.create
=> #<Category id: 1, ...>
>> c.subcategories.create
=> #<Subcategory id: 1, category_id: 1, ...>
>> p = s.products.create
=> #<Product id: 1, subcategory_id: 1, ...>
>> c.products
=> [#<Product id: 1, subcategory_id: 1, ...>]
>> p.category         # if you have the has_one assocation
=> #<Category id: 1, ...>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top