LEFT OUTER JOIN in Rails 4

前端 未结 12 1738
一整个雨季
一整个雨季 2020-11-28 09:44

I have 3 models:

class Student < ActiveRecord::Base
  has_many :student_enrollments, dependent: :destroy
  has_many :courses, through: :student_enrollment         


        
12条回答
  •  情话喂你
    2020-11-28 10:19

    There is actually a "Rails Way" to do this.

    You could use Arel, which is what Rails uses to construct queries for ActiveRecrods

    I would wrap it in method so that you can call it nicely and pass in whatever argument you would like, something like:

    class Course < ActiveRecord::Base
      ....
      def left_join_student_enrollments(some_user)
        courses = Course.arel_table
        student_entrollments = StudentEnrollment.arel_table
    
        enrollments = courses.join(student_enrollments, Arel::Nodes::OuterJoin).
                      on(courses[:id].eq(student_enrollments[:course_id])).
                      join_sources
    
        joins(enrollments).where(
          student_enrollments: {student_id: some_user.id, id: nil},
          active: true
        )
      end
      ....
    end
    

    There is also the quick (and slightly dirty) way that many use

    Course.eager_load(:students).where(
        student_enrollments: {student_id: some_user.id, id: nil}, 
        active: true
    )
    

    eager_load works great, it just has the "side effect" of loding models in memory that you might not need (like in your case)
    Please see Rails ActiveRecord::QueryMethods .eager_load
    It does exactly what you are asking in a neat way.

提交回复
热议问题