我一直在使用
Product.all,但我在填充变量时看到的很多代码都在使用
Product.where(nil)。这个site有一个我发现使用where(nil)的例子。我搜索了文档并找到了哪里(nil)替换了作用域,但不能做出正面或反面的操作。
答案 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,那么查询将会执行。