【问题标题】:Eager loading associations on ActiveModel instances in RailsRails 中 ActiveModel 实例的急切加载关联
【发布时间】:2011-12-17 20:30:35
【问题描述】:

在 RoR 中,新手加载类和关联是很常见的错误# 急切加载的解决方案

# The bellow generates an insane amount of queries
# post has many comments
# If you have 10 posts with 5 comments each
# this will run 11 queries 
posts = Post.find(:all)
posts.each do |post|
  post.comments
end

急切加载的解决方案非常简单

# should be 2 queries
# no matter how many posts you have
posts = Post.find(:all, :include => :comments) # runs a query to get all the comments for all the posts
posts.each do |post|
  post.comments # runs a query to get the comments for that post
end

但是,如果您无法访问类方法,而只能访问实例方法的集合,该怎么办。

然后你就会被查询密集型延迟加载所困。

有没有办法最小化查询以从实例集合中获取posts 集合的所有comments

添加答案(也添加到上面的代码中)


因此,从我在 rdoc for rails 中看到的渴望加载是 ActiveRecord::Associations 的任何扩展上的类方法,问题是说你没有使用类方法的能力,所以你需要使用某种实例方法

我认为它看起来像的代码示例类似于

post = Posts.find(:all)
posts.get_all(:comments) # runs the query to build comments into each post without the class method.

【问题讨论】:

    标签: ruby-on-rails activerecord lazy-loading eager-loading


    【解决方案1】:

    在 Rails 3.0 及更早版本中,您可以这样做:

    Post.send :preload_associations, posts, :comments
    

    您可以传递关联名称的数组或散列,就像您可以包含的那样:

    Post.send :preload_associations, posts, :comments => :users
    

    在 Rails 3.1 中,这已被移动,您可以像这样使用Preloader

    ActiveRecord::Associations::Preloader.new(posts, :comments).run()
    

    自 Rails 4 以来,它的调用已更改为:

    ActiveRecord::Associations::Preloader.new.preload(posts, :comments)
    

    【讨论】:

    • 在 Rails 4 中,可以这样做:ActiveRecord::Associations::Preloader.new.preload(posts,:comments)
    • 使用ActiveRecord::Associations::Preloader有什么阴暗面吗?
    • @swap.nil api 这些年来发生了一些变化,但除此之外,我多年来一直在生产中使用它。
    • 即使在 Rails 5.1 中也可以使用,并且也可以使用单个初始化对象。
    【解决方案2】:

    我想我明白你在问什么。

    但是,我认为您不必担心您可以访问哪些方法。外键关系(以及 ActiveRecord 关联,例如 has_manybelongs_to 等)将负责确定如何加载关联的记录。

    如果您能提供一个您认为应该发生的具体示例,以及不起作用的实际代码,那么您将更容易了解您的理解。

    【讨论】:

    • 上面的例子可能是我能得到的最好的例子。我会补充的
    【解决方案3】:

    您如何获得模型实例的集合,以及您使用的是什么版本的 Rails?

    您是说您绝对无法访问控制器或模型本身吗?

    给你最好的答案取决于了解这些事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多