gpt4 book ai didi

ruby-on-rails - 使用 INNER JOIN 的 Rails ActiveRecord eager_load

转载 作者:行者123 更新时间:2023-12-04 17:50:08 28 4
gpt4 key购买 nike

在大型 Rails 应用程序中,我注意到我们有一段代码可以生成大型 ActiveRecord::Relation。它在 .joins() 调用中使用自定义 SQL 片段——类似这样:

def foos
Foo.
joins("INNER JOIN bars ON foos.bar_id = bars.id").
joins("INNER JOIN baz ON bars.baz_id = baz.id").
where(<some condition on bars>)
end

(请注意,JOIN 比本例中所示的更复杂;否则我显然只会执行 Foo.joins(bar: :baz)。 ) 现在,在一些使用 ActiveRecord::Relation 的地方,这很好。但在其他情况下,我们希望在 Foo 结果集上预先加载 bars 关联。

有没有办法做这样的事情:

def scope_with_bars_eager_loaded
foos.eager_load(:bars, using_existing_join_in_query: true)
end

我能想到的最接近的是:

def array_with_bars_eager_loaded
foos.pluck(<fields we need>).map do |fields|
bar = Bar.new(<get bar data from fields>)

# This of course doesn't behave as well as a Foo
# that we've loaded normally in regards to callbacks,
# fields we didn't SELECT, etc. But it's probably
# fine enough for this use-case (we're using this
# data to render a page).
Foo.new(<get foo data from fields>, bar: bar)
end
end

这要复杂得多,而且也没有给我们带来成为 ActiveRecord::Relation 的好处。如有任何帮助,我们将不胜感激!

--

注意:

任何避免 Rails 默认行为“加载数据库中的每一列,有时在一个查询中多次”的建议都特别受欢迎(这就是为什么我使用 .pluck 而不是 的原因。 select,因为 .select 构造的查询会加载 Foo 中的所有内容,即使您明确告诉它不要这样做)。示例:Foo.includes(:bar).where(bars: { condition: true }).select(:id) 选择 foos 中的每一列,并选择 foos.id 两次

最佳答案

好吧,我最终重组了我的 foos 方法,这样它就可以在那里简单地执行 includes。仍然对所有字段都被 SELECT 编辑感到非常满意,但我想这就是您使用 ActiveRecord 而不是 Sequel 之类的东西所得到的。

关于ruby-on-rails - 使用 INNER JOIN 的 Rails ActiveRecord eager_load,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45723610/

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