Rails 4 Has_many:通过join与join联系

Bil*_*ill 6 ruby activerecord ruby-on-rails ruby-on-rails-3 ruby-on-rails-4

我正在尝试将rails 3.0应用程序升级到rails 4.0.我注意到的一个行为是模型之间的关系停止工作.

假设我们有以下型号:

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
Run Code Online (Sandbox Code Playgroud)

现在我们可以做到:

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
Run Code Online (Sandbox Code Playgroud)

这适用于Rails 3.0,但现在在Rails 4.0上我得到了Unknown column 'met_with_parent' in 'field list'我相信Rails 4试图变得聪明并且没有加载整个给定的连接表.

oma*_*ous 3

我个人会推荐使用范围的以下方法:

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
Run Code Online (Sandbox Code Playgroud)

然后您可以执行以下操作:

Teacher.first.students.met_with_parent
Run Code Online (Sandbox Code Playgroud)

这允许您在需要时维护关系和过滤器。