Active Record: Eager Loading (syntax question)

22 views
Skip to first unread message

Ronald Fischer

unread,
Jul 2, 2014, 8:38:37 AM7/2/14
to rubyonra...@googlegroups.com
Let's have model :parents and :children, where one parent can have many
children, and that I want to do something like this:

plist=Parent.joins(:children).select('*').where("parents.id=children.parent_id
and children.cfield=#{...}")

plist.each { |p| do_something_with(p,p.children) }

Now I learned from
http://guides.rubyonrails.org/active_record_querying.html , that this is
inefficient, due to the SELECT statements generated inside the block,
and that I should do "eager loading" instead. From my understanding of
the tutorial, I should replace 'joins' by 'includes':

plist=Parent.includes(:children).select('*').where("parents.id=children.parent_id
and children.cfield=#{...}")

However, this raises the exception that there would be no column
"children.cfield".

It seems that with 'includes', we can only query based on values of the
Parent table.

Is this correct?

--
Posted via http://www.ruby-forum.com/.

Frederick Cheung

unread,
Jul 2, 2014, 10:37:44 AM7/2/14
to rubyonra...@googlegroups.com
On Wednesday, July 2, 2014 1:38:37 PM UTC+1, Ruby-Forum.com User wrote:
Now I learned from
http://guides.rubyonrails.org/active_record_querying.html , that this is
inefficient, due to the SELECT statements generated inside the block,
and that I should do "eager loading" instead. From my understanding of
the tutorial, I should replace 'joins' by 'includes':

plist=Parent.includes(:children).select('*').where("parents.id=children.parent_id
and children.cfield=#{...}")

However, this raises the exception that there would be no column
"children.cfield".

It seems that with 'includes', we can only query based on values of the
Parent table.

Is this correct?


In rails 4.1  (or possibly 4.0) and later you must use references if you are adding conditions on one of the joined columns, ie

  Parent.includes(:children).references(:children)

So that rails knows it must use the joins based eager loading strategy (rails used to try and guess this for you but this was rather error-prone). You also don't need the select('*')
 
Fred
Reply all
Reply to author
Forward
0 new messages