首页 > 解决方案 > Rails:如何使用 has_many 相关表进行高级查询?

问题描述

我有两个模型。

class Revision < ApplicationRecord
  has_many :revision_approvals
end

class RevisionApproval < ApplicationRecord
  belongs_to :revision
end

修订可以有许多修订批准。RevisionApproval 具有角色(字符串)和决策(枚举 - 整数)字段。角色可以是 process_responsible 或 process_coordinator。process_coordinator 角色高于 process_responsible 角色。修订批准需要 process_coordinator 的决定。如果 process_coordinator 没有做出任何决定,则修订保持待批准状态。如果revision_approval 的角色是process_coordinator,则根据process_coordinator 的决定,revision 的状态由待批准变为已批准或已拒绝。我想要具有待批准状态的修订。我怎样才能用一个查询来做到这一点?

TL;博士

属于修订版的 revision_approvals 不应具有 process_coordinator 角色。这包括没有任何修订批准的修订。

例如:

修订表:

修订号 有没有revision_approval?
577 真的
576 错误的
16 真的
566 真的
384 真的

修订批准表:

修订号 角色 决定
577 process_responsible 0
16 process_responsible 1
16 process_coordinator 1
566 process_responsible 1
384 process_coordinator 0

查询应返回 id 为 566、576、577 的修订。

以下查询返回我想要的记录。过了一会儿如果没有更好的答案,我会添加这个作为答案。

Revision.where.not(
  id: Revision.joins(:revision_approvals)
              .where(revision_approvals: { role: :process_coordinator })
)

标签: sqlruby-on-railspostgresqlactiverecordruby-on-rails-6

解决方案


如果您想要所有修订:

Revision.all

如果您想要具有角色“process_responsible”的角色 revision_approval 的修订:

Revision.joins(:revision_approvals).where(role: "process_responsible")

或者

Revision.joins(:revision_approvals).where("revision_approvals.role = ?",  "process_responsible")

如果您想要具有角色“process_responsible”和 process_responsible 0 的角色 revision_approval 的修订:

Revision.joins(:revision_approvals).where("revision_approvals.role = ? AND revision_approvals.decision = ?",  "process_responsible", 0)

没有修订批准的修订:

Revision.includes(:revision_approval).where(revision_approvals: { id: nil })

推荐阅读