.where(nil)和.all之间有什么区别?

时间:2017-09-09 15:11:55

标签: ruby-on-rails ruby where

我一直在使用

Product.all
,但我在填充变量时看到的很多代码都在使用
Product.where(nil)
。这个site有一个我发现使用where(nil)的例子。我搜索了文档并找到了哪里(nil)替换了作用域,但不能做出正面或反面的操作。

1 个答案:

答案 0 :(得分:1)

我相信曾经存在差异,但是从Rails 4开始就不再有了。这是因为从Rails 4 .all返回一个关系,而它用于返回一个数组。所以以前:

Product.all

立即触发对数据库的查询以返回所有记录,这些记录将被加载到内存中的数组中。基本上你告诉Rails你现在想要数据。有关详细信息,请参阅this question

Product.where(nil) 

创建一个查询(实际上是anonymous scope,返回ActiveRecord:Relation)。

只有在您尝试访问数据时才会执行查询。由于它是作用域,因此您可以链接其他作用域(每次都不会访问数据库),并在访问数据时将整个链作为一个查询执行。

在问题中链接的Justin Weiss文章中,我们看到了这段代码:

def index
  @products = Product.where(nil) # creates an anonymous scope
  @products = @products.status(params[:status]) if params[:status].present?
  @products = @products.location(params[:location]) if params[:location].present?
  @products = @products.starts_with(params[:starts_with]) if params[:starts_with].present?
end

当索引方法结束并返回数据时,该代码将执行一次数据库调用。

但如果您将第一行更改为:

@products = Product.all

该查询将立即执行。然后添加范围,并在索引方法结束时触发另一个查询。这样效率更低。

修改

我相信当您第一次尝试访问@products中的某些数据时,实际上会发生数据库调用(而不是在索引方法结束时)。例如。如果您执行了@ products.first,那么查询将会执行。