Ruby on rails Rails ActiveRecord链是如何运行的;其中;没有多个查询的子句?
我是一名PHP开发人员,正在学习RubyonRails的强大功能,我喜欢ActiveRecord,我注意到了一件非常有趣的事情,那就是ActiveRecord方法如何检测方法链的末端以执行查询Ruby on rails Rails ActiveRecord链是如何运行的;其中;没有多个查询的子句?,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我是一名PHP开发人员,正在学习RubyonRails的强大功能,我喜欢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,
@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
这个魔法是如何工作的?您可以阅读代码,但这里有一个概念是代理模式
可能@person不是真正的对象,而是该对象的代理,当您需要某些属性时,活动记录最终执行查询。Hibernate也有同样的概念。有许多方法被称为“kickers”,它们实际上会向数据库发出查询。在此之前,他们只创建AST节点,一旦启动,将生成实际的SQL(或编译到的语言)并运行查询
@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
有关如何执行此操作的详细说明,请参阅。其中的
方法返回一个ActiveRecord::Relation
对象,并且该对象本身不会发出数据库查询。重要的是你在哪里使用这个物体
在控制台中,您可能正在执行以下操作:
@person = Person.where(name: "Jason")
然后它发出一个数据库查询并返回一个名为Jason的所有人的数组。耶,活动记录
然后你会这样做:
@person = Person.where(name: "Jason").where(age: 26)
然后这又提出了另一个问题,但这个问题是针对26岁的Jason。但是它只发出一个查询,那么另一个查询去了哪里
正如其他人所建议的,这是因为where
方法返回一个代理对象。除非要求它执行查询并返回数据集,否则它实际上不会执行查询并返回数据集
当您在控制台中运行任何内容时,它将输出您运行的任何内容的结果的检查版本。如果您将1
放入控制台并按enter键,您将返回1
,因为1.inspect
是1
。魔术这同样适用于“1”
。许多其他对象都没有定义inspect
方法,因此Ruby会回到Object
上的方法,该方法返回类似
的可怕信息
每个ActiveRecord::relationship
对象都定义了inspect
方法,以便引发查询。当您在控制台中编写查询时,IRB将对该查询的返回值调用inspect
,并输出几乎是人类可读的内容,如您看到的数组
如果您只是在标准Ruby脚本中发出此命令,那么在检查对象(通过inspect
)或使用each
迭代对象,或调用to_a
方法之前,不会执行任何查询
在这三件事中的一件发生之前,您可以在上面链接任意多个where
语句,然后当您调用inspect
,对其上的每个或进行检查时,它将最终执行该查询。可能有点晚了,但您可以使用哈希:
@person=person.where({姓名:“Jason”,年龄:26})
结果查询:
从“person”中选择“person”。*其中“person”。“name”=“Jason”和“person”。“age”=26
它在最后一个方法中不执行此操作。它无法知道这一点。考虑<代码> x=人。person=x。其中(..)
,其执行方式应相同。它会在以后某个时候发生,那么触发因素是什么呢?;-)用Rails源代码解释它。person=person.where({name:“Jason”,age:26})和person=person.where(name:“Jason”,age:26)完全相同-Ruby会自动将第二个的参数转换为散列