0

I have three activerecord models:

the "A"

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

the middle:

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

the B:

class Violation < ApplicationRecord
end

I need to find all users who have AT LEAST one violation with column: fatal set to true.

Im kinda stuck here and this is not working:

User.joins(:violations).where('violations.fatal = true')
Giova.panasiti
  • 447
  • 3
  • 11

3 Answers3

3

To using query filter conditon in ORM I think this syntax should be:

User.joins(:violations).where(violations: {fatal: 'true'})
Ninh Le
  • 1,291
  • 7
  • 13
1

I think @Ninh Le's answer is right,(so did yours!) maybe you can simplify your models' code first to try to find where the problem is. For example, I notice you missed the 's' in the has_many relation:

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

I think it should work, if it's still not, check if there is record that has violation.fatal == true.

Then add the options of has_many, belongs_to if there 'really' needed.

kevinluo201
  • 1,444
  • 14
  • 18
0

For the most efficient approach to finding these users, you'd want what the database people would call a "semi-join" - an exists subquery.

Assuming that "fatal" is defined by a fatal column having a value of true

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

I'd suggest adding a scope to Violation that defines fatal without needing a where clause in that.

David Aldridge
  • 51,479
  • 8
  • 68
  • 96