在我的方案中,我有一个BlogPost
模型has_and_belongs_to_many :categories
。我想过滤 out 属于特定类别的博客帖子,同时仍允许未分类的博客帖子(因此需要左外联接)。
我希望这可行:
BlogPost.active.includes(:categories).where.not(categories: { id: [1, 2, 3] })
但它没有正确过滤,因为它将条件放在查询的末尾,在LEFT OUTER JOIN之外(请参阅此SO问题/答案,原因是:SQL join: where clause vs. on clause)
这很有效,但很难看:
BlogPost.active.joins("LEFT OUTER JOIN blog_posts_categories
ON blog_posts_categories.blog_post_id = blog_posts.id
AND blog_posts_categories.category_id NOT IN(1, 2, 3)")
是否有一种ActiveRecord友好的方式将条件添加到LEFT OUTER JOIN的ON子句而不用我的方式手动输入?
答案 0 :(得分:0)
我认为这可能有用。
BlogPost.active.joins(:categories).merge(Category.where.not(categories: { id: [1,2,3] })
并将其与范围一起添加,以获取所有没有类别的博客帖子。另一个想法是改为使用has_many through
关系,并实际为BlogPostCategory
创建模型,因为您可以在其上添加中间范围。
答案 1 :(得分:0)
我并不完全熟悉ActiveRecord语法,但是您可以扩展过滤器以包含category_id IS NULL
的行吗?这将满足您的要求。