...これは、以下のはるかに簡潔なバージョンがあり、1つの簡単な方法ですが、そのもう一つは最初にせずに理解することは困難です
考えるフィルタ条件ですprice
、platform
とavailability
...
フォームフィールドに適切な名前を付けてください。params hash
の一部として表示されます。これは、そのフィルタフィールドの値がない限り、適切な条件で#where
を経由して、あなたのフィルターを通して段階的に説明し、それぞれ1を適用し、その後、すべての製品のプレースホルダで始まる
@products = Product.where(true)
%w(price platform availability).each do |filter|
unless params[filter.to_sym].nil?
@products = @products.where(filter => params[filter.to_sym])
end
end
:次に、あなたのコントローラでこのような何かを実行しますnil
です。最後に、商品インスタンス変数にフィルタリングされたコレクションが保持されます。これは、ActiveRecordクラスの#whereメソッドがchainable
で、別の#whereを適用できるたびにRelation
オブジェクトを返すためです。
最初の.where(真)の部分はちょっとハッキリですが、入れないと、すべてのフィルタがnilでない場合、@productsはすべての製品のコレクションではなくProductクラスのオブジェクトになります。 #allメソッドは廃止されました。したがって、私は.where(true)を使用しています。これを行うためのより良い方法またはより受け入れやすい方法があるかどうかはわかりません。
Rails 3では、コレクション上でenumerable method
(#each
のような)を呼び出すまで、実際にDBに対して何も実行されないので、これはdbに対してうまくいくはずです。
より簡潔なバージョンはこれです...
@products = Product.where(params.select {|key, value| %w(price platform availability).include?(key.to_s) && !value.nil?})
あなたは#whereメソッドに条件のentire hash
に渡すことができますので、これは動作します。 #of呼び出し内のparams.select
部分のコードは、params
ハッシュからすべてのキーと値のペアを引き出します。ここで、キーはフィルタ条件の1つと一致しますand
値はnon-nil
であり、生成されたハッシュは#whereに供給されます。これは、上記のall-filters-nil issue
を持たないようです。なぜなら、すべてがnilの場合、#whereは空のハッシュを取得してすべてを選択するからです。
使用しているRailsのバージョンは何ですか? – Yardboy
現在実行中3.1.rc5 –