该where
方法返回一个ActiveRecord::Relation
对象,并且该对象本身不会发出数据库查询。重要的是你使用这个对象的地方。
在控制台中,您可能正在这样做:
@person = Person.where(name: "Jason")
然后blammo它发出一个数据库查询并返回似乎是一个名为 Jason 的每个人的数组。耶,活动记录!
但是你做这样的事情:
@person = Person.where(name: "Jason").where(age: 26)
然后发出另一个查询,但这个查询是针对 26 岁的叫 Jason 的人。但它只发出一个查询,那么另一个查询去哪儿了?
正如其他人所建议的那样,发生这种情况是因为该where
方法返回了一个代理对象。它实际上并不执行查询并返回数据集,除非它被要求这样做。
当您在控制台中运行任何内容时,它将输出您运行的任何结果的检查版本。如果您1
输入控制台并按回车键,您将1
返回,因为1.inspect
is 1
。魔法!也一样"1"
。许多其他对象没有inspect
定义方法,因此 Ruby 回退到Object
返回可怕的东西的对象<Object#23adbf42560>
。
每个ActiveRecord::Relation
对象都inspect
定义了方法,因此它会引发查询。当您在控制台中编写查询时,IRB 将调用inspect
该查询的返回值并输出几乎人类可读的内容,例如您看到的数组。
inspect
如果您只是在标准 Ruby 脚本中发出此命令,则在检查(通过)对象或通过 using 迭代each
或to_a
调用该方法之前不会执行任何查询。
在这三件事中的一件发生之前,您可以在其上链接任意数量的where
语句,然后当您调用时inspect
,to_a
或者each
在其上,它最终将执行该查询。