在已检索的关联上使用范围的最佳实践

时间:2014-11-26 10:10:38

标签: ruby-on-rails activerecord associations

class Foo < ActiveRecord::Base
  has_many :bars
end

class Bar < ActiveRecord::Base
  belongs_to :foo

  def self.activated
    where(activated: true)
  end
end

class FoosController < ApplicationController
  def index
    @foos = Foo.includes(:bars)
  end
end

我想说我想要显示所有Foos的表格,包括其上的激活条数。为了防止N + 1个查询,我在检索所有Foos时已经包含了:bar。但是,如果我使用foo.bars.activated,Rails会激活另一个查询,而不知道已经检索到的条形图。

我在这里看到两个选项:

  1. 不使用范围,而是过滤已检索的对象: foo.bars.select(&:activated)
  2. 定义另一个自定义关联,限定为已激活的栏:has_many :activated_bars, -> { where(activated: true) }, class_name: 'Bar'
  3. 还有其他(更好)的方法吗?

1 个答案:

答案 0 :(得分:1)

以下内容将仅使用已激活的栏加载所有foo,并且还将eager_load栏加载

 Foo.eager_load(:bars).merge(Bar.activated)

更新:

或者您也可以在Foo和eager_load上定义新的作用域关系

#Foo
has_many :activated_bars, ->{ activated }, clas_name: 'Bar'

#foos_controller#index
Foo.includes(:activated_bars)

另见http://blog.bigbinary.com/2013/07/01/preload-vs-eager-load-vs-joins-vs-includes.html