JOIN ON … AND conditions when eager loading association in ActiveRecord

前端 未结 2 1496
南笙
南笙 2021-01-23 12:58

Please notice, this is not a question about adding a WHERE condition to an association but a rather advanced question about how to alter the JOIN clause when using eager

相关标签:
2条回答
  • 2021-01-23 13:08

    EDIT

    This does not solve the problem stated.


    You cannot alter the JOIN generated by calling eager_load like you want. The WHERE clause is your only option, and it has the exact same effect as the condition on your JOIN. Here it is, even if you didn't want it:

    Parent.eager_load(:grades).where("grades.level = 'A+'")
    
    0 讨论(0)
  • 2021-01-23 13:24

    If I am right, you only want to eager load the subset of the associations. Well, in order to do so, you need to outsmart the rails . You can basically create another association such as "highest_grade" to fetch the grades with level A+ using a where clause inside the ruby lambda. This can be achieved by using the following snippet of code

    class Parent
      has_many :children
      has_many :grades, through: :children
      has_many :highest_grade, ->{where(level: 'A+')}, class_name: "Grade", through: :children
    end
    

    Now you need to eager load the highest_grade association.

     Parent.eager_load(:highest_grades)
    

    This will essentially load all the parents along with only those grades whose level is A+.

    It generates the following query.

     SQL (0.3ms)  SELECT `parents`.`id` AS t0_r0, `parents`.`created_at` AS    t0_r1, `parents`.`updated_at` AS t0_r2, `grades`.`id` AS t1_r0,    `grades`.`child_id` AS t1_r1, `grades`.`created_at` AS t1_r2, `grades`.`updated_at` AS t1_r3, `grades`.`level` AS t1_r4 FROM `parents` LEFT OUTER JOIN `children` ON `children`.`parent_id` = `parents`.`id` LEFT OUTER JOIN `grades` ON `grades`.`child_id` = `children`.`id` AND `grades`.`level` = '
    

    If you want to understand how does this work. Please use this link as a reference

    0 讨论(0)
提交回复
热议问题