我在使用条件时使用相关表格的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
答案 0 :(得分:0)
我猜你正在寻找的是joins
方法,它会让你把你的条件放在连接定义中,而不是在它之外。例如:
@post = Post.joins("LEFT JOIN comments on posts.id = comments.post_id AND comments.approved = 1").first
不确定条件本身的正确性,但你明白我的观点。
不幸的是,如果你传递数组/哈希,你必须使用那个丑陋的字符串,因为joins
正在使用INNER JOIN。
答案 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