Rails如何对一个模型的多个请求执行SQL查询?

时间:2018-06-21 06:02:00

标签: ruby-on-rails activerecord

不确定我是否正在正确阅读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

同一个问题。

2 个答案:

答案 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,则只会触发一个查询