该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
是1
。魔法!同样适用"1"
。许多其他对象都没有inspect
定义方法,因此Ruby退回到了一个Object
返回可怕的东西的对象<Object#23adbf42560>
。
每个单个ActiveRecord::Relation
对象都具有在inspect
其上定义的方法,以便它引起查询。当您在控制台中编写查询时,IRB将调用inspect
该查询的返回值,并输出几乎人类可读的内容,例如您看到的Array。
如果您只是在标准Ruby脚本中发布此代码,则只有在检查了该对象(通过inspect
)或使用对其进行了迭代each
或to_a
调用了方法之后,才会执行查询。
直到发生这三件事之一,您都可以where
在其上链接任意数量的语句,然后在调用或对其进行调用时inspect
,它最终将执行该查询。to_a
each
x = Person.where(..); @person = x.where(..)
,其性能应相同。稍后它会执行,那么触发了什么?;-)