Lost in Queries (n:m followed by 1:n)

Given the following relations (see bottom of post) n:m Users - Tabs (has_many has_many; trough sharedtabs) 1:n Tabs - Tasks (has_many and belongs_to)

I am stuck in the queries: @test = User.find(2).tabs.find(3).tasks ← all tasks in tab #3 of user 2, works

I want to query all tasks that belong to all tabs of a particular user @test = User.find(2).tabs.tasks ← undefined method tasks @test = User.find(2).tabs.find(:all).tasks ← undefined method tasks

I most likely will bang my head against the wall seeing the solution, still, I read doc after doc without a solution except stepping through each of the user tabs one after the other :confused:

class User < ActiveRecord::Base

Include default devise modules. Others available are:

:token_authenticatable, :confirmable, :lockable and :timeoutable

devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable

Setup accessible (or protected) attributes for your model

attr_accessible :email, :password, :password_confirmation, :remember_me

has_many :sharedtabs, :dependent => :destroy has_many :tabs, :through => :sharedtabs, :dependent => :destroy end

class Tab < ActiveRecord::Base has_many :tasks, :dependent => :destroy

has_many :sharedtabs, :dependent => :destroy has_many :users, :through => :sharedtabs end

class Sharedtab < ActiveRecord::Base belongs_to :user belongs_to :tab
end

class Task < ActiveRecord::Base belongs_to :tab end

bourne wrote in post #971069:

Given the following relations (see bottom of post) n:m Users - Tabs (has_many has_many; trough sharedtabs)

That should probably be :shared_tabs.

1:n Tabs - Tasks (has_many and belongs_to)

I am stuck in the queries: @test = User.find(2).tabs.find(3).tasks <-- all tasks in tab #3 of user 2, works

I want to query all tasks that belong to all tabs of a particular user @test = User.find(2).tabs.tasks <-- undefined method tasks @test = User.find(2).tabs.find(:all).tasks <-- undefined method tasks

Of course! Tasks is only defined for individual Tab objects, not for an array of them.

What you need to do is create an additional :through relation, so that User has_many :tasks, :through => :tabs . You may have to use the nested_has_many_through plugin.

Best,

I think the problem is that youre trying to call a tasks method from an Array Class, you should do that for a Tab class, so try this, i didnt tested but i think it can help:

User.find(particular_user_id).tabs.collect {|c| c.tasks}.flatten

Good luck,

Fernando Santos

Please quote when replying.

Fernando Leandro wrote in post #971088:

I think the problem is that you`re trying to call a tasks method from an Array Class, you should do that for a Tab class, so try this, i didn`t tested but i think it can help:

User.find(particular_user_id).tabs.collect {|c| c.tasks}.flatten

However, this is a very poor solution. It performs many unnecessary DB queries, and I would never recommend its use. Using :through takes advantage of DB joins, which is the proper way.

Good luck,

Fernando Santos

Best,

What you need to do is create an additional :through relation, so that User has_many :tasks, :through => :tabs . You may have to use the nested_has_many_through plugin.

Marnen, thanks for pointing me in the right direction. Still, I did not suceed. The plugin you mentioned is outdated (not working with Rails3). Direct usage

class User < ActiveRecord::Base has_many :sharedtabs, :dependent => :destroy has_many :tabs, :through => :sharedtabs, :dependent => :destroy

has_many :tasks, :through => :tabs end

results in: “SQLite3::SQLException: no such column: tabs.user_id: SELECT “tasks”.* FROM “tasks” INNER JOIN “tabs” ON “tasks”.tab_id = “tabs”.id WHERE ((“tabs”.user_id = 1))”

Anyway, there is a lighthouse ticket on that: https://rails.lighthouseapp.com/projects/8994/tickets/1152-support-for-nested-has_many-through-associations (and so this might be available in Rails in future).

Still my question remains what to do in Rails 3.0.3?