9

I need to preload associations of the model with complex conditions. NO, includes doesn't work for me. It generate wrong SQL for my task.

I take a look to the ActiveRecord::Associations::Preloader and find that he take an preload_scope argument:

http://apidock.com/rails/v4.2.1/ActiveRecord/Associations/Preloader/preload

 def preload(records, associations, preload_scope = nil)
  # ...
 end

But I can't find any example using it. What is preload_scope in this case? And how I can use it for filtering associations? Thanks!

Vladimir
  • 103
  • 1
  • 9

1 Answers1

4

ActiveRecord doesn't expose this through #preloads on relation: https://github.com/rails/rails/blob/0aefa97689d001ca9a98db76bbad1bbbb0e51c9c/activerecord/lib/active_record/relation.rb#L663 – as you can see only records and associations parameters are passed.

You can reach into ActiveRecord internals and call Preloader directly:

rows = Projects.all.to_a
ActiveRecord::Associations::Preloader.new.preload(rows, :current_task, Struct.new(:values, :bind_values).new({where: "active"}, []))
Wojtek Kruszewski
  • 11,222
  • 6
  • 32
  • 37
  • Oh, thanks, it works! But why it creates so many queries? `User Load (12.1ms) SELECT "users".* FROM "users" WHERE (created_at > '2015-01-01') AND "users"."cat" IN (52, 50, 51, 53) User Load (1.2ms) SELECT "users".* FROM "users" WHERE (created_at > '2015-01-01') User Load (5.1ms) SELECT "users".* FROM "users"` – Vladimir Apr 30 '15 at 10:01
  • `users = Car.find(1).users rows = users.to_a ActiveRecord::Associations::Preloader.new.preload(rows, :activities, Struct.new(:values, :bind_values).new({where: "created_at > '2015-01-01'"}, []))` – Vladimir May 13 '15 at 13:52
  • 1
    The excessive number of queries was also highlighted [here](https://github.com/rails/rails/issues/20704) (but not investigated by Rails team since they consider Preloader private stuff) – Kombajn zbożowy Nov 07 '15 at 21:43
  • How could you use the `preload_scope` to return a limit? For example return only 5 elements? – Steven Aguilar Mar 13 '21 at 22:31