什么时候执行ActiveRecord查询?

时间:2018-06-21 05:13:13

标签: ruby-on-rails ruby ruby-on-rails-3

我对Ruby如何执行查询感到困惑:

让我们假设有两种方法:

def meet1
   user = User.all
end

每次我调用此方法时,都会运行一个查询,内容为:

  

'用户负载(18.3ms)选择“ users”。*从“ users”内部联接“ roles”到“ roles”。“ user_id” =“ users”。“ id” WHERE“ users”。“ banned” = 'f'和“ roles”。“描述” ='gogetter'

这意味着它查询用户...

让我们假设我有另一种方法:

def meet2
  user = User.all
  user.to_sql
end

当我称呼它时,它返回了该查询的SQL格式:

所以我的问题是在第一种方法中查询得到执行,但是在第二种方法中查询得到执行了吗?还是它只是向我显示最终结果而不执行查询,因为我从未使用过它?

2 个答案:

答案 0 :(得分:1)

user = User.all除了创建潜在查询外什么也不做,并将其副本spawn放入user中。这遵循“构建器模式”;然后user可以说user.joins(...)user.order(...)来建立一个不同的潜在查询。它们都返回一个spawn版本的查询副本。

meet1的操作将触发对数据库的实际命中。我怀疑像p meet1这样无害的东西,甚至是您的IRB shell,都可以将spawn版本的潜在数据库查询评估为Enumeration,然后命中数据库。

答案 1 :(得分:1)

我也希望您也来看看this answer

  

当您调用User.all时,它将返回User::ActiveRecord_Relation对象,并且该对象本身不会发出数据库查询。在这里使用此对象很重要。

因此,当调用met1时,它会发出查询,但是如果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?

在这种情况下,在任何情况下?和any_other_condition?是的,它只执行一个查询,将所有3件事.all和所有where条件合并。

我希望您看看blog here,其中显示了一些kickers方法,这些方法将使您更加清楚自己的方式。