ActiveRecord .joins() 并在连接模型上使用 .where(),其中 2 个"IN"条件由一个"OR"连接



问题

我有一个PostComment,我想选择帖子,并在包含OR和具有2个IN条件的Comment上使用.joins().where()

我想要一个生成这个的东西:

SELECT * FROM posts
INNER JOIN comments ON comments.post_id = posts.id
WHERE comments.id IN (1,2,3) OR comments.user_id IN (4,5,6)

我会使用.or()方法,但它不能使用哈希。

Post.joins(Comment)
.where({ comments: { id: [1, 2, 3] } })
.or({ comments: { user_id: [4, 5, 6] } })      # <-- raises exception

可能的解决方案

为了便于阅读,我对其进行了简化。事实上,我需要这一点来跨数据库适配器工作,所以我会使用Comment.connection.quote_table_nameComment.connection.quote_column_name来正确引用表名和列名。

ids = [1,2,3]
user_ids = [4,5,6]
clause = ""
clause += Comment.sanitize_sql_for_conditions(["comments.id IN (?)", ids]) if ids.any?
clause += " OR " if ids.any? and user_ids.any?
clause += Comment.sanitize_sql_for_conditions(["comments.user_id IN (?)", user_ids]) if user_ids.any?
Post.joins(Comment).where(clause)

问题

这是有效的,但似乎应该有更好的方法。。。有吗?

我假设您的Post类与has_many :comments有注释关系,Rails非常聪明,知道当您使用带有关系名称的.where时,您会考虑每个注释的id,然后您可以简单地编写id。

要使用OR,您必须使用将用于构造主查询的同一类,它就像OR中的"子查询",就像follow。

请尝试使用下一个代码:

Post.joins(:comments)
.where(comments: [1, 2, 3])
.or(Post.where('comments.user_id IN ?', [4, 5, 6]))

轨道或:https://zaiste.net/rails_5_or_operator_active_record/
联接:https://apidock.com/rails/ActiveRecord/QueryMethods/joins

编辑

由于这个答案引用了已知的问题,您应该使用原始SQL,如follow。

Post.joins(:comments)
.where('comments.id in ? OR comments.user_id in ?', [1, 2, 3], [4, 5, 6])

原始sql中的每个?都将替换为按相同顺序从左到右传递给.where的参数。

相关内容

  • 没有找到相关文章

最新更新