人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

Railsで使用しているActiveRecordについて質問です。

レコード取得の条件をリクエストパラメータの指定の有無によって動的に作成したいです。

リクエストパラメータが2つあり、それを仮にparams[:a]とparams[:b]とします。
(1)両方が指定されている場合
where hoge = params[:a] and fuga = params[:b]
(2):aのみが指定されている場合
where hoge = params[:a]
(3):bのみが指定されている場合
where fuga = params[:b]

上記のように動的に条件を組み立てる実装方法を教えてください。

Rails:3.0.5
ActiveRecord:3.0.5

●質問者: Gaasu
●カテゴリ:コンピュータ ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● nuna
●100ポイント

モデルのクラス名をItemとします。
また、とりあえず簡便のためaもbも指定しなかった場合はすべて返すとします。
実際には、必要に応じてパラメタのチェックなどしてください。

items = Item.all
if params[:a].present
items = items.where(hoge => params[:a])
end
if params[:b].present
items = items.where(fuga => params[:b])
end

Rails3のActiveRecordでは条件を追加しながらSQLを組み立てていくことができます。
上のコードではパラメタa b両方があった場合には、
items = Item.all
items = items.where(hoge => params[:a])
items = items.where(fuga => params[:b])
となり、これは以下と同じです。
items = Item.where(hoge => params[:a]).where(fuga => params[:b])

一度に条件を指定する場合は、
items = Item.where(hoge => params[:a], fuga => params[:b])
のようにも書けます。

http://gihyo.jp/dev/serial/01/ruby/0043 辺りを参照ください。


Gaasuさんのコメント
返信が遅くなり申し訳ありません。 回答ありがとうございます。 例どおりに実装してみましたが、エラーが発生してしまいました。 (undefined method `where' for #<Array:0xa2ca6dc>) どうやら、Item.allを評価した時点でクエリが実行され、遅延ロードされていないようです。 試しに以下のようなコードで実行してみたところ、遅延ロードは正常に機能しました。 items = Item.where(:hoge => params[:a]) items = items.where(:fuga => params[:b]) 今のところ、allもしくはfindを評価するとその時点でクエリが実行されてしまうことが実際に動かしてみて分かりました。 この理由は分かりますでしょうか? 分かりましたらまた回答をお願い致します。

nunaさんのコメント
すみません。勘違いしてました。 allはRails2.x以前からあるAPIで(仕様として)遅延評価しないので、私の書き方だとダメですね。 ですので、試されたようにallは使わず書いてください。

Gaasuさんのコメント
コメントありがとうございます。 allを使わない実装を考えてみます。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ