我是一名 PHP 开发人员,正在学习 Ruby on Rails 的神奇之处,我喜欢 ActiveRecord,并且我注意到一些非常有趣的事情,这就是 ActiveRecord 方法如何检测方法链的末尾以执行查询。
@person = Person.where(name: 'Jason').where(age: 26)
# In my humble imagination I'd think that each where() executes a database query
# But in reality, it doesn't until the last method in the chain
这个魔法是如何运作的?
最佳答案
where
方法返回 ActiveRecord::Relation
对象,并且该对象本身不发出数据库查询。重要的是在哪里使用这个对象。
在控制台中,您可能会执行以下操作:
@person = Person.where(name: "Jason")
然后blammo它发出一个数据库查询并返回一个似乎是名为 Jason 的每个人的数组。耶,事件记录!
但是你做了这样的事情:
@person = Person.where(name: "Jason").where(age: 26)
然后会发出另一个查询,但这个查询是针对 26 岁、名叫 Jason 的人的。但它只发出一个查询,那么另一个查询去哪儿了?
<小时/>正如其他人所建议的,发生这种情况是因为 where
方法返回一个代理对象。它实际上并不执行查询并返回数据集,除非要求这样做。
当您在控制台中运行任何内容时,它将输出您运行的结果的检查版本。如果你输入 1
在控制台中按 Enter 键,您将得到 1
回来因为1.inspect
是 1
。魔法! "1"
也是如此。各种其他对象没有 inspect
定义了方法,因此 Ruby 回退到 Object
上的方法它返回一些可怕的东西,比如 <Object#23adbf42560>
.
每一个ActiveRecord::Relation
对象有 inspect
其上定义的方法,以便引发查询。当您在控制台中编写查询时,IRB 将调用 inspect
根据该查询的返回值并输出一些几乎人类可读的内容,例如您看到的数组。
如果您只是在标准 Ruby 脚本中发出此命令,则在检查对象(通过 inspect
)或通过使用 each
迭代对象之前,不会执行任何查询。 ,或者有to_a
方法调用它。
在这三件事之一发生之前,您可以链接尽可能多的 where
根据您的喜好对其进行陈述,然后当您确实调用 inspect
时, to_a
或each
上,然后它最终会执行该查询。
关于ruby-on-rails - Rails ActiveRecord 如何在没有多个查询的情况下链接 "where"子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10747106/