Rails ActiveRecord eager_load with INNER JOIN

时间:2017-08-16 21:54:59

标签: ruby-on-rails ruby-on-rails-4 activerecord

在一个大型的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 两次

1 个答案:

答案 0 :(得分:0)

好吧,我最终重组了我的foos方法,以便它可以在那里执行includes。对SELECT编辑的所有字段仍然不满意,但我想这是使用ActiveRecord代替Sequel之类的内容。