在一个大型的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
s比此示例中显示的更复杂;否则我显然只做Foo.joins(bar: :baz)
。)现在,在{{1}的某些地方使用,这很好。但在其他情况下,我们希望在ActiveRecord::Relation
结果集上加载bars
关联。
有没有办法做这样的事情:
Foo
我能提出的最接近的事情是:
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
的好处。这里的任何帮助将不胜感激!
-
注意:
任何避免Rails&#39;的建议&#34;默认行为加载数据库中的每一列,有时在一个查询中多次加载#34;特别感谢(这就是为什么我使用ActiveRecord::Relation
代替.pluck
,因为.select
构建了加载.select
中所有内容的查询,即使您明确告诉它不要)。示例:Foo
选择Foo.includes(:bar).where(bars: { condition: true }).select(:id)
中的每一列,然后选择foos
两次。
答案 0 :(得分:0)
好吧,我最终重组了我的foos
方法,以便它可以在那里执行includes
。对SELECT
编辑的所有字段仍然不满意,但我想这是使用ActiveRecord
代替Sequel
之类的内容。