gpt4 book ai didi

ruby-on-rails - JOIN ON ... 以及在 ActiveRecord 中急切加载关联时的条件

转载 作者:行者123 更新时间:2023-12-04 12:51:52 24 4
gpt4 key购买 nike

请注意,这不是关于向关联添加 WHERE 条件的问题,而是关于如何在使用 eager_load 时更改 JOIN 子句的高级问题。

假设我有这些模型

class Parent
has_many :children
have_many :grades, through: :children
end

class Child
belongs_to :parent
end

class Grade
belongs_to :child
end

所以为了急切加载我会做的 parent :

Parent.eager_load(:grades)

但是如果我想要所有的 parent ——但只是像这样急切地加载最高分:

LEFT OUTER JOIN grades ON grades.child_id = children.id AND grades.level = 'A+'

我尝试过使用 includes(:children).joins("LEFT OUTER JOIN grades ON grades.child_id = children.id AND grades.level = 'A+'") 但是因为 Rails 不构建关联对象,这将导致对每个父级的额外查询。

我没有找到任何关于将 eager_load 与自定义 SQL 字符串一起使用的引用资料,并且有 dug through the source没有变得更聪明。

最佳答案

如果我是对的,您只想预先加载关联的子集。那么,为了做到这一点,您需要超越 rails。您基本上可以创建另一个关联,例如“highest_grade”,以使用 ruby​​ lambda 中的 where 子句获取 A+ 级的成绩。这可以通过使用以下代码片段来实现

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

现在您需要预加载 highest_grade 关联。

 Parent.eager_load(:highest_grades)

这实际上将加载所有家长以及仅那些级别为 A+ 的成绩。

它生成以下查询。

 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` = '

如果你想了解它是如何工作的。请使用this link as a reference

关于ruby-on-rails - JOIN ON ... 以及在 ActiveRecord 中急切加载关联时的条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33716153/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com