migu
migu

Reputation: 4336

Fetching records through multiple tables

The image shows part of my data model. I would like to fetch all items that are associated with a user (through organizations and items_group). How should I change the models and write this query in the controller? Using :through => organizations I can get all items_groups but I don't how to include one more relation to query related items.

enter image description here

class User < ActiveRecord::Base           
  has_and_belongs_to_many :organizations
  has_many :items_groups, :through => :organizations         
end

class Organization < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_and_belongs_to_many :items_groups
  has_many :items, :through => :items_groups  
end

class ItemsGroup < ActiveRecord::Base  
  has_many :items, :inverse_of => :items_group
  has_and_belongs_to_many :organizations
  has_many :users, :through => :organizations             
end

Upvotes: 1

Views: 2587

Answers (2)

Shadwell
Shadwell

Reputation: 34774

I think you might have to do it back-to-front and find items joined back to your user.

You could define method like this in your User class:

def items
  Item.joins(:items_group => {:organizations => :users}).where("users.id" => self.id).select("distinct items.*")
end

The items it returns will be read-only because of the explicit select but I think you'll want that to avoid returning individual items more than once.

Upvotes: 4

felipeclopes
felipeclopes

Reputation: 4070

If you set in your models the relationships this should work:

users.organizations.item_groups.items

Though for it to work your models should contain this:

class User < ActiveRecord::Base         
  has_many :organizations, :through => :organization_users
end

class Organization < ActiveRecord::Base
  has_many :item_groups, :through => :items_groups_organizations
end

class ItemsGroup < ActiveRecord::Base  
  belongs_to :item
end

Hope it works for you!

Upvotes: 0

Related Questions