何时会执行ActiveRecord查询?

7
我是一位能翻译文本的助手。

我对Ruby如何执行查询存在困惑:

假设我们有两个方法:

def meet1
   user = User.all
end

每次调用这个方法时,我都会得到一个查询运行的结果,它说:
'用户加载(18.3毫秒)从“users”内部联接“roles”,使用“roles”内的“user_id”=“users”中的“ID”选择“users”。"."在“users”中,“banned”='f'并且“roles”中的“description”='gogetter'
这意味着它查询了用户...
假设我有另一个方法:
def meet2
  user = User.all
  user.to_sql
end

当我调用此方法时,它会返回该查询的 SQL 格式:

所以我的问题是,在第一种方法中,查询是否被执行了?而在第二种方法中,查询是否被执行?还是只是显示最终结果而没有执行查询,因为我从未使用它?

2个回答

7
user = User.all 只是创建一个潜在的查询,并将其复制到 user 中。这遵循了“构建者模式”;user 随后可以使用 user.joins(...) 或者 user.order(...) 来构建一个不同的潜在查询。它们都返回一个 spawn 的查询副本。

你对 meet1 进行的操作会触发实际访问数据库的操作。我怀疑像 p meet1 或者你的 IRB Shell 这样的无害操作,可能会将 spawn 的潜在数据库查询作为一个 Enumeration 进行评估,从而导致访问数据库。


5

我希望你能看一下这个答案

当你调用User.all时,它返回一个User::ActiveRecord_Relation对象,但是这个对象本身并不会发出数据库查询。重要的是你如何使用这个对象。

所以当调用meet1时,它会发出查询,但是在meet2的情况下,User.all发出关系对象,user.to_sql发出与数据库相关的查询。

当你尝试基于条件链接多个过滤器时,你可以看到同样的事情发生了。

u = User.all
u = u.where(name: "Hello") if any_condition?
u = u.where(last_name: 'world') if any_other_condition?

在这种情况下,当in any_condition?和any_other_condition?都为true时,它只会执行一个查询,合并所有的3个thing.all和where条件。
我希望你看一下这里的博客,它展示了一些kickers方法,这将让你更清楚地了解这种方式。

3
一个可能会引起困惑的地方 - 如果你在irb或rails控制台中运行这个命令,每输入一行代码后,控制台都会尝试去评估结果并执行它。 - JohnFlux
1
@user3342930 IRB和Rails控制台都在幕后使用IRB。IRB是Read-Eval-Print Loop,因此只要用户键入任何内容(除非我们谈论块),Rails控制台和IRB都会直接发出查询。 以下链接非常有用,可以了解IRB: https://www.digitalocean.com/community/tutorials/how-to-use-irb-to-explore-ruby - Manishh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接