Rails发出两个数据库查询

时间:2013-06-15 18:22:05

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

这是Rails 4.0.0.rc2,创建了一个版本化的API。

我有一个简单的模型“用户”,有很多字段。在Controller的show操作中,我想限制从数据库中获取的字段数(构建投影)。所以,而不是

SELECT "users".* FROM "users" ...

我想发出

SELECT id, first_name, last_name, email FROM "users" ...

我认为,我已经完成了这项工作,但效果不佳:Rails发出两个数据库查询。

详情

为此,我在模型中定义了scope

class User < ActiveRecord::Base
  ...
  scope :brief, -> (id) { select('id, first_name, last_name, email').where('id == ?', id) }
end

Controller的show操作定义为此

def show
  if derived_version >= 2
    @user = User.brief(params[:id])
  else        
    @user = User.find(params[:id])  
  end
end

(使用版本蛋糕进行版本控制)

在版本2中,范围用于构建投影。版本1只包含关系中的所有列。

这是有效的,除了Rails在使用范围时发出两个数据库查询,其中FIRST是奇数:

Started GET "/api/users/2?api_version=2" for 127.0.0.1 at 2013-06-15 19:49:11 +0200
Processing by Api::UsersController#show as JSON
  Parameters: {"api_version"=>"2", "id"=>"2"}
  User Load (0.1ms)  SELECT id, first_name, last_name, email FROM "users" WHERE (id == '2') ORDER BY "users"."id" ASC LIMIT 1
  User Load (0.3ms)  SELECT id, first_name, last_name, email FROM "users" WHERE (id == '2')
  Rendered api/users/show.v2.json.rabl (89.0ms)
Completed 200 OK in 99ms (Views: 92.5ms | ActiveRecord: 1.0ms)

当我在这种情况下切换到版本1时

@user = User.find(params[:id])  

将被执行,日志就像我期望的那样:

Started GET "/api/users/2?api_version=1" for 127.0.0.1 at 2013-06-15 20:03:56 +0200
Processing by Api::UsersController#show as JSON
  Parameters: {"api_version"=>"1", "id"=>"2"}
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", "2"]]
  Rendered api/users/show.v1.json.rabl (1.1ms)
Completed 200 OK in 6ms (Views: 4.5ms | ActiveRecord: 0.3ms)

我尝试过多种变体,例如将select()。where()直接放入控制器的show动作中,但结果总是相同的:当使用select()时,OR在哪里()或select()。where()Rails生成两个查询。

所以,在我提出最后一个问题之前,我需要补充一点,我不是Rails专家。

问题

我是否认为Rails实际上执行了这两个数据库查询?

发出两个查询是否有任何好的/令人信服的理由?

0 个答案:

没有答案