ActiveRecordy has_many 通过我需要找到所有 parents 其中至少有一个 child 满足条件

ActiveRecordy has_many through I need to find all parents where at least one child meet the condition

我有三个 activerecord 模型:

“A”

class User < ApplicationRecord
  has_many :user_violation, class_name: "UserViolation", inverse_of: :user
  has_many :violations, through: :user_violation, class_name: "Violation"
end

中间:

class UserViolation < ApplicationRecord
  belongs_to :user, class_name: "User", foreign_key: :user_id
  belongs_to :violation, class_name: "Violation", foreign_key: :violation_id
end

乙:

class Violation < ApplicationRecord
end

我需要找到至少有一项违规行为的所有用户:fatal 设置为 true。

我有点卡在这里,这不起作用:

User.joins(:violations).where('violations.fatal = true')

在ORM中使用查询过滤条件我认为这个语法应该是:

User.joins(:violations).where(violations: {fatal: 'true'})

我认为@Ninh Le 的回答是正确的,(你的也是!)也许你可以先简化你模型的代码,试图找出问题所在。 例如,我注意到您错过了 has_many 关系中的 's':

class User < ApplicationRecord
  has_many :user_violations
  has_many :violations, through: :user_violations
end

class UserViolation < ApplicationRecord
  belongs_to :user
  belongs_to :violation
end

class Violation < ApplicationRecord
  # has_many :user_violations
  # has_many :violations, through: :user_violations
end

我认为应该可以,如果还是不行,请检查是否有 violation.fatal == true 的记录。

如果需要'really',则添加has_many、belongs_to选项。

为了找到这些用户的最有效方法,您需要数据库人员所说的 - 存在子查询。

假设“fatal”由值为 true

fatal 列定义
User.
  where(
  Violation.
    where(fatal: true).
    joins(:user_violations).
    where(
      UserViolation.arel_table[:user_id].eq(User.arel_table[:id])
    ).arel.exists
  )

我建议为定义 fatal 的 Violation 添加范围,而无需其中的 where 子句。