Conditions on a has_many :through and ActiveRecord 4.1 enum


Say you have a set of models (model names sanitized for generic posting) where the join table in the middle of a has_many :through has an enum that you want to add a filtered association for.

class Student < ActiveRecord::Base
    has_many :student_grades
    has_many :grades, through: :student_grades
  end

  class StudentGrade < ActiveRecord::Base
    enum approval_status: [:not_reviewed, :rejected, :approved]
    belongs_to :student
    belongs_to :grade
  end

  class Grade
  end

I ended up creating two additional has_many associations on Student to accomplish this. I have to specify a condition on :approved_student_grades, and tell it what class name (StudentGrade) to point to because reflection through the association name won't work. I really dislike the verbosity of StudentGrade.approval_statuses[:approved] as a way to get the integer value of the enum (in this case, 2). For the :approved_grades association, I also have to repeat a similar process, except I have to specify both the class_name: and the source: due to reflection not working for :approved_grades.

class Student < ActiveRecord::Base
  has_many :student_grades
  has_many :grades, through: :student_grades
  has_many :approved_student_grades, -> {where approval_status: StudentGrade.approval_statuses[:approved] }, class_name: "StudentGrade"
  has_many :approved_grades, through: :approved_student_grades, class_name: "Grade", source: :grade
end

I'd be surprised if there wasn't a cleaner way to do this, but enum is new in Rails 4.1, so that may be part of my problem.


%d bloggers like this: