Ramoji
Ramoji

Reputation: 110

How to model belongs_to through association

I have the three models Category,ItemType and Item.In plain english i can put my requirement as:A Category can have zero or more itemtypes.A ItemType must belong to only a single category and can have zero or more items.An Item belongs to an itemtype and a category thru the itemtype.i've associated them as below:

 class Category < ActiveRecord::Base
   has_many :item_types
   has_many :items ,:through => item_types, :source => category
 end  
 class ItemType < ActiveRecord::Base
   has_many :items
 end
 class Item < ActiveRecord ::Base
   belongs_to :item_type
 end

Now How can i associate an item with a category.One of my views need to show all the items of a category. When i query it as

   Category.joins(:item_types,:items).where("categories.id=?",1)

i get the below sql

  SELECT "categories".* FROM "categories" INNER JOIN "item_types" ON "item_t
  ypes"."category_id" = "categories"."id" INNER JOIN "item_types"   
  "item_types_categories_join" ON "item_types_categories_join"."category_id" =
  "categories"."id" INNER JOIN "categories" "items_categor
  ies" ON "items_categories"."id" = "item_types_categories_join"."category_id" WHERE
  (categories.id=1)

Can anyone help me out here.How to get the below sql

 select * from categories 
      inner join item_type on categories.id=item_types.category_id
      inner join items on item_types.id=items.item_type_id
 where categories.id =1

Upvotes: 0

Views: 279

Answers (3)

Samiron
Samiron

Reputation: 5317

Something like this should work

#this will load your item_types and items earlier with less query.
Category.find(1, :include => [:item_types, :items])

Also your models needs following changes

 class ItemType < ActiveRecord::Base
 ... ...
 +    belongs_to :category
 end

 class Item < ActiveRecord::Base
 ... ...
 +    belongs_to :category
 end

Here is a related link - Rails Active Record: find in conjunction with :order and :group. You might get more details here.

Upvotes: 1

HungryCoder
HungryCoder

Reputation: 7616

If I am correct, the association declaration is incomplete. You may need to add belongs_to :category in ItemType & Item model. For example:

class Category < ActiveRecord::Base
   has_many :item_types
   has_many :items ,:through => item_types
 end  
 class ItemType < ActiveRecord::Base
   has_many :items
   belongs_to :category
 end
 class Item < ActiveRecord::Base
   belongs_to :item_type
   belongs_to :category
 end

now an instance of category should be able to list all the items. As you wanted to list all items of a category, you should get it by:

cat = Category.find_by_id(ID_GOES_HERE)
cat.items

Upvotes: 1

Atastor
Atastor

Reputation: 741

I am not sure I would rely on rails magic here. Can you try

Category.includes([:item_types,:items]).where(['items.item_type_id = ?',categories.item_type.id]).where(<...your conditions...>)

Sorry for not having time to check it myself before posting :-(

Upvotes: 0

Related Questions