Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4 Has_many :through join association with select

I am trying to upgrade a rails 3.0 app to rails 4.0. One of the behaviour I noticed is the relationship between the models stopped working.

Assume we have the following models:

class Student < ActiveRecord::Base
  has_many :teacher_students
  has_many :teachers, :through => :teacher_students, :select => 'teacher_students.met_with_parent, teachers.*'

  # The Rails 4 syntax
  has_many :teachers, -> { select('teacher_students.met_with_parent, teachers.*') }, :through => :teacher_students

end

class Teacher < ActiveRecord::Base
  has_many :teacher_students
  has_many :students, :through => :teacher_students, :select => 'teacher_students.met_with_parent, students.*'
end

class TeacherStudent < ActiveRecord::Base
  belongs_to :teacher
  belongs_to :student
  # Boolean column called 'met_with_parent'
end

Now we are able to do:

teacher = Teacher.first
students = teacher.students
students.each do |student|
  student.met_with_parent     # Accessing this column which is part of the join table
end

This worked for Rails 3.0, but now on Rails 4.0 I am getting Unknown column 'met_with_parent' in 'field list' I believe Rails 4 is trying to be smart and not loading the entire given join tables.

like image 777
Bill Avatar asked Jun 25 '13 17:06

Bill


1 Answers

I personally would recommend the following approach, using scopes:

class Student < ActiveRecord::Base
  has_many :teacher_students
  has_many :teachers, :through => :teacher_students
end

class Teacher < ActiveRecord::Base
  has_many :teacher_students
  has_many :students, :through => :teacher_students

  scope :met_with_parent, -> { joins(:teacher_students).where('teacher_students.met_with_student = ?', true) }
end

class TeacherStudent < ActiveRecord::Base
  belongs_to :teacher
  belongs_to :student
end

Then you can do the following:

Teacher.first.students.met_with_parent

This allows you to maintain the relationships AND filter when needed.

like image 88
omarvelous Avatar answered Oct 30 '22 19:10

omarvelous