【问题标题】:How to set preload scope for Rails Associations::Preloader?如何为 Rails Associations::Preloader 设置预加载范围?
【发布时间】:2015-04-30 17:01:40
【问题描述】:

我需要预加载模型与复杂条件的关联。不,includes 不适合我。它为我的任务生成错误的 SQL。

我查看了ActiveRecord::Associations::Preloader,发现他接受了preload_scope 参数:

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

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

但我找不到任何使用它的示例。在这种情况下,preload_scope 是什么?以及如何使用它来过滤关联? 谢谢!

【问题讨论】:

    标签: ruby-on-rails activerecord preloader


    【解决方案1】:

    ActiveRecord 不会通过 #preloads 公开此关系: https://github.com/rails/rails/blob/0aefa97689d001ca9a98db76bbad1bbbb0e51c9c/activerecord/lib/active_record/relation.rb#L663 – 如您所见,仅传递了记录和关联参数。

    您可以进入 ActiveRecord 内部并直接调用 Preloader:

    rows = Projects.all.to_a
    ActiveRecord::Associations::Preloader.new.preload(rows, :current_task, Struct.new(:values, :bind_values).new({where: "active"}, []))
    

    【讨论】:

    • 哦,谢谢,它有效!但是为什么它会创建这么多查询呢? 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"
    • 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'"}, []))
    • 过多的查询也被突出显示here(但 Rails 团队没有调查,因为他们认为 Preloader 是私有的)
    • 如何使用preload_scope 来返回限制?例如只返回 5 个元素?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 2014-01-26
    • 2011-12-17
    • 2022-01-18
    • 2021-08-30
    • 2013-09-01
    • 1970-01-01
    相关资源
    最近更新 更多