bil*_*lal 5 ruby ruby-on-rails ruby-on-rails-3
我对 Ruby 如何执行查询感到困惑:
假设我们有两种方法:
def meet1
user = User.all
end
Run Code Online (Sandbox Code Playgroud)
每次我调用这个方法时,我都会运行一个查询,它说:
'用户负载 (18.3ms) SELECT "users".* FROM "users" INNER JOIN "roles" ON "roles"."user_id" = "users"."id" WHERE "users"."banned" = 'f' AND "roles"."description" = 'gogetter''
这意味着它查询用户...
假设我有另一种方法:
def meet2
user = User.all
user.to_sql
end
Run Code Online (Sandbox Code Playgroud)
当我调用它时,它返回了该查询的 SQL 格式:
所以我的问题是在第一种方法中执行查询,但是查询是否在第二种方法中执行?或者它只是向我显示最终结果而不执行查询,因为我从未使用过它?
user = User.all除了创建一个潜在的查询并将spawn其副本复制到user. 这遵循“构建器模式”;user然后可以说user.joins(...), 或user.order(...), 来构建不同的潜在查询。它们都返回spawn查询的编辑副本。
您所做的操作meet1会触发对数据库的实际命中。我怀疑像p meet1,甚至是你的 IRB shell 这样无害的东西,可以将spawned 潜在数据库查询评估为Enumeration,然后访问数据库。
我也想让你看看这个答案
当您调用
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?
Run Code Online (Sandbox Code Playgroud)
在这种情况下 in any_condition? 还有任何其他条件吗?是的,它只执行一个查询,合并所有 3 件事 .all 和所有 where 条件。
我希望您看看这里的博客,它展示了一些kickers方法,这将使您更清楚地了解该方法。