Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails ActiveRecord链是如何运行的;其中;没有多个查询的子句?_Ruby On Rails_Activerecord - Fatal编程技术网

Ruby on rails Rails 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,

我是一名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, 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会自动将第二个的参数转换为散列