1

これは Rails 4.0.0.rc2 で、バージョン管理された API を作成します。

いくつかのフィールドを持つ単純なモデル「ユーザー」があります。コントローラーのshowアクションで、データベースからフェッチされるフィールドの数を制限したいと思います (プロジェクションの構築)。だから、代わりに

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

発行したい

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

これは達成できたと思いますが、望ましくない結果が生じました。Rails は2 つのデータベース クエリを発行します。

詳細

その目的のためにscope、モデルでa を定義しました。

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

コントローラーのshowアクションは次のように定義されます

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

(バージョン管理には versioncake を使用)

バージョン 2 では、スコープはプロジェクションの構築に使用されます。バージョン 1 では、リレーションにすべての列が含まれています。

これは機能しますが、Rails はスコープが使用されたときに 2 つのデータベース クエリを発行し、最初のクエリは奇数です。

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 where() OR select().where を使用する場合() Rails は 2 つのクエリを生成します。

ですから、最後の質問をする前に、私は Rails の専門家ではないことを付け加えておく必要があります。

質問

Rails が実際にこれら 2 つのデータベースクエリを実行するという仮定は正しいでしょうか?

2 つのクエリを発行する正当な/説得力のある理由はありますか?

4

0 に答える 0