【发布时间】:2012-03-27 10:13:18
【问题描述】:
我正在运行 Ruby on Rails 3.1。我阅读了以下关于eager loading的文章和文档,我想找到一种正确的方法来做事:
- Eager Loading Associations【官方文档】
- ActiveRecord::Associations::ClassMethods(参见“渴望加载关联”部分)[官方文档]
- Eager loading[博文]
#2 说:
请注意,使用 Post.includes([:author, :cmets]).where(['cmets.approved = ?', true]).all 之类的条件可能会产生意想不到的后果。
#3 表示这些意外后果是(注意:示例几乎相同,因此我引用了博客文章的确切文字,但您必须保留注意解决方法,而不是具体的实现):
这个查询,因为它会使用 LEFT JOIN,所以也会丢弃所有在它的任何 cmets 上没有带有“first”字样的评论的帖子。
也就是说,如果存在非“关联”对象,则不会加载“主要关联”对象。这就是我尝试通过在我的previous question 中添加一些条件(如.where(:category_relationships => {:user_id => @current_user.id}))来使用急切加载时发生的情况,但我不希望这种情况发生。
所以(失败者,因为在我无法在 has_many 语句中设置 条件 的情况下,我可能无法使用即时加载 - 请注意,在上面的代码中 @current_user.id 是“动态设置”,与上述网站中的示例不同),我想知道是否有实践/技术/策略,以便限制数据库查询,因为我有一个“N + 1 问题”。 p>
也许这些实践/技术/策略完全可以通过使用 Ruby on Rails 框架来实现……#1 说:
即使 Active Record 允许您在 Eager 上指定条件 加载关联就像连接一样,推荐的方法是使用 而是加入。
什么以及如何以正确的方式解决这个问题?
也许一个解决方案是通过运行特定和分离的数据库查询来检索和构建自己需要加载的内容,但是问题将是如何“传递”/“关联”/“插入”那些检索到的“关联”对象到“主要关联”对象,以便那些可以使用“急切加载”的方式?也就是说,如何使可能(有关更多信息,请参阅mentioned question)使用像@这样的代码987654329@ 并且只获得我渴望自己加载的 cmets?在 我的 急切加载之后,是否 可能 / 正确 制作像 @article.comments = my_eager_loaded_comments 这样的东西来“通过”/“关联”/“插值” " cmets 到文章?
【问题讨论】:
标签: ruby-on-rails ruby database ruby-on-rails-3 eager-loading