“筛选”急切加载的数据时出现问题

用户名

我正在使用Ruby on Rails 4,并且我想了解为什么即使在急切加载数据的情况下,在急切加载过程中还要运行更多的SQL查询。也就是说,我有以下渴望:comments正确加载代码的代码

@articles = @current_user.articles.includes(:comments)

当以上代码运行并且我使用以下代码“跟踪”记录器中发生的情况:

@articles.each do |article|
  logger.debug article.comments
end

然后记录器说:

Article Load (0.4ms) SELECT ...
Comment Load (0.5ms) SELECT ... WHERE `articles`.`id` IN (...)

#<ActiveRecord::Associations::CollectionProxy [#<Comment id: 1, title: "Hello A">, #<Comment id: 2, title: "Hello B">]>

#<ActiveRecord::Associations::CollectionProxy [#<Comment id: 3, title: "Hello A">, #<Comment id: 4, title: "Hello C">]>

#<ActiveRecord::Associations::CollectionProxy [#<Comment id: 5, title: "Hello D">, #<Comment id: 6, title: "Hello E">]>

...

上面的输出表明,急切的加载正在按预期的方式进行:由于ActiveRecord::Associations::CollectionProxy运行时已加载对象,因此没有N + 1问题article.comments

但是,当我尝试运行如下代码时(请注意该find_by子句):

@articles.each do |article|
  logger.debug article.comments.find_by(:title => "Hello A")
end

然后记录器说:

Article Load (0.4ms) SELECT ...
Comment Load (0.5ms) SELECT ... WHERE `articles`.`id` IN (...)

Comment Load (0.4ms) SELECT ... AND `comments`.`title` = 'HELLO A'
#<Comment id: 1, title: "Hello A">

Comment Load (0.4ms) SELECT ... AND `comments`.`title` = 'HELLO A'
#<Comment id: 3, title: "Hello A">

Comment Load (0.4ms) SELECT ... AND `comments`.`title` = 'HELLO A'
nil

...

上面的输出表明,急切的加载未按预期工作:每个注释都运行一个SQL查询。

因此,我的问题/疑问是:

  1. 为什么在最后一种情况下,该find_by子句使急切的加载不起作用(请注意:即使在我article.comments使用而不是子句“过滤”情况下,它也会发生find_by)?
  2. Ruby on Rails是否应该将已经加载到ActiveRecord::Associations::CollectionProxy对象中的数据作为数组进行处理,从而避免访问数据库?
  3. 我如何解决该问题以避免最后一种情况下的N + 1问题?
保罗·里希特

只是确认一下:David Underwood是正确的,find_by它将进行数据库调用。事实上,find_by基本上只是一个包装wheretake,这的确会让一个DB调用。

完成您要查找的内容的另一种方法是,通过使用find方法,将收集代理简单地视为一个数组,如下所示:

@articles.each do |article|
    logger.debug article.comments.find {|comment| comment.title == "Hello A"}
end

更新:

我不得不承认,这有点令人生厌。

以您想要的方式完成此操作的方法是添加另一个has_many专门包含所需过滤条件的关系,如下所示:

class Article < ActiveRecord::Base

    has_many :hello_A_comments, -> { where(title: "Hello A") }, class_name: "Comment"

    # rest of class
end

然后,您渴望使用此新关联进行加载,如下所示:

@articles = @current_user.articles.includes(:hello_A_comments)

这部分非常重要:现在,您不是通过原始:comments关联方法访问关联,而是通过新hello_A_comments方法访问关联,如下所示:

@articles.first.hello_a_comments

不幸的是,如您所见,此方法不是很动态,而遗憾的是,在急切加载的情况下,我不知道如何在关联中考虑可变条件。这个答案可能是一个很好的参考资源,但是在急于加载的情况下,老实说,我认为它不可能。如果这是一个问题,那么您可能会遇到前面提到的数组方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类常见问题

在Julia中加载CSV文件时出现问题

来自分类Dev

ASP.NET MVC:使用kendoDatePicker筛选kendoGrid时出现问题

来自分类Dev

MediaElement.js在加载时出现问题

来自分类Dev

将XML文件数据加载到PHP对象中时出现问题

来自分类Dev

加载Microsoft Visual菜单时出现问题

来自分类Dev

向数据库插入数据时出现问题

来自分类Dev

从AndroidKeystore加载私钥时出现问题

来自分类Dev

访问XML数据时出现问题

来自分类Dev

在RecyclerView内加载AdView时出现问题

来自分类Dev

NavigationLink SwiftUI导致加载图像时出现问题

来自分类Dev

EFCore急切加载问题

来自分类Dev

在Julia中加载CSV文件时出现问题

来自分类Dev

尝试获取数据时出现问题

来自分类Dev

WebGL-加载纹理时出现问题

来自分类Dev

从文件jQuery数组加载数组时出现问题

来自分类Dev

在Android中加载Google Map时出现问题

来自分类Dev

加载jquery接口时出现问题,

来自分类Dev

加载链接列表时出现问题

来自分类Dev

Prism和IEventAggregator:加载模块时出现问题

来自分类Dev

使用按钮动画加载场景异步时出现问题

来自分类Dev

从云存储加载数据时出现问题,至少需要改进错误消息

来自分类Dev

django 1.7:加载测试的初始夹具时出现问题

来自分类Dev

Android Studio切换主题时出现问题

来自分类Dev

PHP从数据库读取数据时出现问题

来自分类Dev

向数据库插入数据时出现问题

来自分类Dev

Rails&Youtube API:加载iframe时出现问题

来自分类Dev

加载文件时emacs出现问题

来自分类Dev

在急切加载时别名 Eloquent 关系

来自分类Dev

在 AsyncTack 中加载位图时出现问题