Bob
Bob

Reputation: 8504

Rails 3 activerecord children of children records

My models:

class Person
 has_many :projects

class Project
 belongs_to :person
 has_many :tasks

class Task
 belongs_to :project

Given a person instance, person = Person.find(10), is there an easy way to access all the tasks that belongs to all the projects for the person? In addition, I would need to further filter the projects results if projects.duration < x days sort of thing. I could try to manually construct the resultset by person.projects and then looping through each project to get the associated tasks but I'm hoping there is another simpler more elegant syntax that I'm not aware of. BTW, person.projects.tasks doesn't work.

Upvotes: 4

Views: 3235

Answers (1)

dombesz
dombesz

Reputation: 7909

Yes, there is a more elegant way to do it. You can eager load the results. Let me show you.

without filtering the person list

person = Person.find(10).includes(:projects=>:tasks)

This will eager load you the results so if you call person.projects.first.tasks.first its already loaded and no more sql queries will be executed.

If you'd like to filter them do something like this:

person = Person.where('people.id=10 AND projects.duration < ?', x).includes(:projects=>:tasks)

If you'd like to iterate just on all the tasks without iterating through the projects you have to set up a relation like:

class Person
  has_many :projects
  has_many :tasks, :through=>:projects
end  

To iterate them do something like:

person = Person.find(10)
person.tasks.where('projects.duration < ?', x)

Upvotes: 9

Related Questions