Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 925
Bob Avatar asked Jan 17 '23 19:01

Bob


1 Answers

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)
like image 185
dombesz Avatar answered Jan 29 '23 07:01

dombesz