Rails 3关于渴望加载的关联的条件

时间:2011-02-03 23:31:41

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

我在使用条件时使用相关表格的Rails 3时遇到了麻烦。似乎Rails在加载原始模型数据时应用条件,因此它不会加载父模型,除非非零数量的子/关联模型与条件匹配。这在代码中更容易解释(例如简化):

@post = Post.includes(:comments).where(:comments => { :approved => true }).find(1)

这将生成类似于:

的SQL查询
SELECT DISTINCT `posts`.id FROM `posts`
LEFT OUTER JOIN `comments` ON `comments`.`post_id` = `posts`.`id`
WHERE (`comments`.`approved` = 1) AND (`posts`.`id` = '1')
LIMIT 1

如果没有符合approved = 1条件的注释,则不返回任何行,因此Post永远不会被加载。

根据评论条件,热切地加载帖子及相关评论的正确方法是什么?

更新

我很想听到一个更好的方法来做到这一点,但是现在我正在使用以下方法解决它(使用深度嵌套的急切加载):

@post = Post.find(1)
@comments = @post.comments.where(:approved => true).all

# allows deeper/more complex nesting without getting into SQL:
@post = Post.includes(:author => [ :websites, :photo ]).find(1)
@comments = @post.comments.includes(:editor).where(:approved => true).all

2 个答案:

答案 0 :(得分:0)

我猜你正在寻找的是joins方法,它会让你把你的条件放在连接定义中,而不是在它之外。例如:

@post = Post.joins("LEFT JOIN comments on posts.id = comments.post_id AND comments.approved = 1").first

不确定条件本身的正确性,但你明白我的观点。

不幸的是,如果你传递数组/哈希,你必须使用那个丑陋的字符串,因为joins正在使用INNER JOIN。

还有更多about joins at rails guides

答案 1 :(得分:0)

更新this post on includes vs eager_load vs preload可能会有一些智慧。

我仍然希望听到一种更好的方法,但是现在我正在使用以下方法解决它(与深度嵌套的急切加载一起使用,与使用joins不同):

@post = Post.find(1)
@comments = @post.comments.where(:approved => true).all

# allows deeper/more complex nesting without getting into SQL:
@post = Post.includes(:author => [ :websites, :photo ]).find(1)
@comments = @post.comments.includes(:editor).where(:approved => true).all