ruby-on-rails - ActiveRecord .joins() 并在连接模型上使用 .where(),其中 2 个“IN”条件由“OR”连接
问题描述
问题
我有一个Post
和一个Comment
,我想选择帖子并在包含一个和两个条件的评论上使用一个.joins()
和一个。.where()
OR
IN
我想要产生这个的东西:
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_name
并Comment.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 中的“子查询”,就像跟随一样。
请尝试使用下一个代码:
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,如下所示。
Post.joins(:comments)
.where('comments.id in ? OR comments.user_id in ?', [1, 2, 3], [4, 5, 6])
原始 sql 中的每个?
都将替换为以相同顺序从左到右.where
传递的参数。
推荐阅读
- laravel - 使用 FormData 将数据从 Vue 传递到 Laravel 的整数问题
- android - 我应该在哪里使用单例,我应该在哪里为 1 活动应用程序使用视图模型?
- flutter - 颤振:使用带有页面的导航器时如何处理后退按钮按下
- java - Springboot 2.4.0-RC1 和 Spring Cloud Config (Illford) - java.lang.VerifyError:无法从最终类继承
- reactjs - Antd - 如何使用异步数据默认扩展表中的所有树项?
- java - 在Java中读取括号内的内容?
- sql - 如何让最后一行在 Oracle SQL 中显示聚合函数
- r - 按观察出现的时间过滤
- java - 测试覆盖仅调用另一个方法的方法的最佳方法是什么?
- python - 使用循环从更大的列表中保存新列表