Rails包含()LEFT OUTER JOIN和自定义ON子句

nch*_*rro 9 sql activerecord join ruby-on-rails rails-activerecord

在我的场景中,我有一个BlogPost模型has_and_belongs_to_many :categories.我想筛选属于特定的类别,同时仍允许未分类的博客文章(因此需要一个LEFT OUTER JOIN)博客文章.

我希望这可行:

BlogPost.active.includes(:categories).where.not(categories: { id: [1, 2, 3] })
Run Code Online (Sandbox Code Playgroud)

但它没有正确过滤,因为它将条件放在查询的末尾,在LEFT OUTER JOIN之外(请参阅此SO问题/答案,原因是:SQL join:where子句与on子句)


这有效,但很难看:

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)")
Run Code Online (Sandbox Code Playgroud)

是否有一种ActiveRecord友好的方式来添加条件到LEFT OUTER JOIN的ON子句而不用我的方式手动输入它?

Sea*_*ean 1

我认为这可能有效。

BlogPost.active.joins(:categories).merge(Category.where.not(categories: { id: [1,2,3] })
Run Code Online (Sandbox Code Playgroud)

并将其与一个范围添加在一起,该范围可以获取所有没有类别的博客文章。另一个想法是使用has_many through关系,并实际创建一个模型,因为BlogPostCategory您可以在其上添加中间范围。