我对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格式:
所以我的问题是在第一种方法中查询得到执行,但是在第二种方法中查询得到执行了吗?还是它只是向我显示最终结果而不执行查询,因为我从未使用过它?
答案 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
方法,这些方法将使您更加清楚自己的方式。