Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4 eager load for an object

I'm trying to eager load an association from an instantiated object, i.e. instead of reading the associations together with parent object...

User.includes(:characters).first

...defer it until I decide it's really needed and do something like:

u = User.first
# Other stuff ...
u.eager_load(:characters)

In Rails 3 I enhanced ActiveRecord with this method:

def eager_load(*args)
  ActiveRecord::Associations::Preloader.new(self, *args).run
end

And it worked fine. Rails 4 changed this part a bit and I updated the method to:

def eager_load(*args)
  ActiveRecord::Associations::Preloader.new.preload(self, *args)
end

Unfortunately, it now does something weird. Take a look:

2.1.2 :001 > u = User.first
[2015-01-06 23:18:03] DEBUG ActiveRecord::Base :   User Load (0.3ms)  SELECT  `users`.* FROM `users`  ORDER BY `users`.`id` ASC LIMIT 1
 => #<User id: 1, ...> 
2.1.2 :002 > u.eager_load :characters
[2015-01-06 23:18:07] DEBUG ActiveRecord::Base :   Character Load (0.2ms)  SELECT `characters`.* FROM `characters` WHERE `characters`.`user_id` IN (1)
[2015-01-06 23:18:07] DEBUG ActiveRecord::Base :   Character Load (0.3ms)  SELECT `characters`.* FROM `characters`
[2015-01-06 23:18:07] DEBUG ActiveRecord::Base :   Character Load (0.2ms)  SELECT `characters`.* FROM `characters`
 => [#<ActiveRecord::Associations::Preloader::HasMany:0x00000007c26d28 @klass=Character(id: integer, ...), @owners=[#<User id: ...], @reflection=#<ActiveRecord::Reflection::HasManyReflection:0x0000000496aa60 @name=:characters, ...(LOTS of stuff here)...] 

Note especially the double SELECT of all records. Is there a way to fix this behaviour or some other method to do what I want?

like image 611
Kombajn zbożowy Avatar asked Jan 06 '15 22:01

Kombajn zbożowy


1 Answers

I had the same problem and tracing back my steps I noticed this could be an artifact of running this code on the console. Every expression gets evaluated, but we are only interested in the side product: If this is the case try:

u.eager_load(:characters); nil

I hope it help, I'm currently working on this, so this is my only observation so far.

like image 112
Leonel Galán Avatar answered Nov 05 '22 20:11

Leonel Galán