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?