ruby-on-rails - Rails - 获取父ID不在任何子关联中的对象
问题描述
我有这两个模型:
Collabs
- id
- title
# has_many :collaborations
Collaborations
- collab_id
- user_id
- status
# belongs_to :collab
# belong_to :user
在查询中,我不想获取所有协作,其中某个 user_id 不存在于子(协作)关联中。一个协作可以有零到多个协作,并且协作将具有不同的 user_id。
我试过(使用范围):
collabs = Collab.available_for_user(2)
scope :available_for_user, -> (user_id) { joins(:collaborations).where.not(collaborations: {user_id: user_id}) }
我也试过:
scope :available_for_user, -> (user_id) { left_outer_joins(:collaborations).where.not(collaborations: {user_id: user_id}) }
这是在控制台中输出的 SQL:
SELECT "collabs".* FROM "collabs" LEFT OUTER JOIN "collaborations" ON "collaborations"."collab_id" = "collabs"."id" WHERE ("collaborations"."user_id" != $1) [["user_id", 13]]
如果子关联仅具有提供的 user_id,但如果协作与另一个 user_id 有另一个协作,则此协作有效,则使用上述范围获取此协作。
解决方案
这是你的电话:
Collab.find_by_sql [
"SELECT *
FROM collabs
WHERE id NOT IN (
SELECT C.id
FROM collabs C
JOIN collaborations CL ON CL.collab_id = C.id
WHERE CL.user_id = :user_id)",
{ user_id: user_id }
]
说明:要获取所选 user_id 没有协作的协作,有必要找到具有协作的协作,并排除它们。:)
如果没有 SQL,使用普通的 Ruby,它可以写成:
Collab.where.not(
id: Collab.joins(:collaborations)
.where(collaborations: { user_id: user_id })
.pluck(:id)
)
或者,更多细节:
# Inner query to find collabs with collaborations for given user_id:
# SELECT C.id
# FROM collabs C
# JOIN collaborations CL ON CL.collab_id = C.id
# WHERE CL.user_id = :user_id
ids = Collab.joins(:collaborations)
.where(collaborations: { user_id: user_id })
.pluck(:id)
# Final query:
# SELECT *
# FROM collabs
# WHERE id NOT IN :ids
Collab.where.not(id: ids)
它产生两个 SQL 调用,而不是第一种情况下的一个(find_by_sql),所以为了性能起见,请避免这样做。
推荐阅读
- c - 更改按钮样式(C win32)
- ios - 您的规范来源都不包含满足依赖项的规范:Firebase (~> 6.33.0)、Firebase (= 6.33.0, ~> 6.33.0)
- javascript - 如何在使用 jquery 填写表单之前禁用提交表单按钮?
- php - 为 Laravel 8 路由定义命名空间
- javascript - 使用 React Hooks,使用“useState”和“useEffect”,有没有办法渲染一个状态,直到状态有一个值?
- python - python __module__ dunder 是 __main__
- ios - Xcode 12.0 iOS 13+ UIViewController() viewWillDisappear() 问题
- python-3.x - 摆脱 Python shapefile 图中的多余线条?
- mongodb - MongoDB查询基于最大日期的最后一次查询
- ssh - 本地 pgAdmin 连接到 Digitalocean postgres 液滴