不确定我是否正在正确阅读Puma日志。所以我想澄清三件事:
第一
如果在控制器中我们执行类似的操作:
def find_user
user = User.where(name: "Alex")
@user = user.where(age: 25)
end
进行了多少次SQL查询?
第二
def find_user
user = User.where(name: "Alex")
@user = user
end
同一个问题。
第三
def find_user
user = User.find(1).id
@user = User.find(1).first_name
end
同一个问题。
答案 0 :(得分:3)
第三段代码生成2个DB查询,从技术上来讲,第一段和第二段生成0。如果使用@user
变量或返回值,则可能生成任何查询 find_user
方法(显然是同一件事)。
此行为背后的原因是ActiveRecord
使用查询的延迟评估,因此可以在需要结果时执行它们。
控制台输出经常会误导您,所有这些调用都在一个地方执行,如果您一个接一个地执行它们,则会生成SQL查询,但这只是因为在后台,控制台会在每个求值对象上调用inspect
值,以生成输出,这就是ActiveRecord
收到消息的地方,“哦,我需要实际执行数据库操作才能获得所需的结果”。考虑以下示例,您可以在控制台中对其进行检查:
lambda do
user = User.where(name: "Alex")
@user = user.where(age: 25)
return 'any other value'
end.call
您将从此lambda表达式中返回'any other value'
字符串,但是猜猜是什么-@user
变量将设置为容纳ActiveRecord::Relation
实例,并且将生成0个数据库查询。
答案 1 :(得分:0)
在Ruby on Rails ActiveRecord中,除非使用ActiveRecord的对象来获取某些记录或执行某些会影响您的数据库的操作,否则不会进行任何SQL查询。
因此,在第一种情况下,与第二种情况相同,对数据库只有一个查询。但是在第三种情况下,如果同时使用user
和@user
来获取记录,则会触发两个查询,因为它们都是不同的对象。如果您仅使用@user
,则只会触发一个查询