- ベストアンサー
Rails3初心者のための金額絞り込み検索方法
- rails3を勉強中の初心者のために、DBに登録された商品の一覧から金額で絞り込み検索をする方法をご紹介します。
- indexに検索結果が表示されない問題について、productsコントローラーのsearch_priceアクションのコードを説明します。
- さらに、viewsファイルのコードについても説明し、初心者の方でも理解しやすくなるようにしました。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
def search_priceを以下のようにしてください def search_price @products = Product.where('price >=? AND price <= ?',params[:price1],params[:price2]) render :action => 'index' end ---------------------------------------------- 結果を表示する views/products/index.html では @productsに指定範囲のレコードが複数格納されていることを前提にしています。 しかしながら、 @products = Product.all で全レコードが取得されているため、その内容がそのまま(結果として)全レコード表示されます。 私が、記述した方法は、価格が指定範囲内に収まるレコードを取得してその結果を@products にセットしています。 全レコードを取得後、each do で、個々のレコードを参照する方法は、 全レコードの数が少ない場合は、問題ありませんが、多い場合(例えば数千件)は、パフォーマンス上 問題があります。多くのレコードの中からある条件を満足するレコードを取得する場合は、 通常、その処理をDB側に任せます。(つまり今回のようにwhereメソッドなどで範囲を指定します) そうすると、DB側でレコードの絞込みを行なうので、結果として返されるレコード数が非常に削減され レスポンスの向上につながります。
その他の回答 (1)
- tatsu99
- ベストアンサー率52% (391/751)
#1です。 参考までに全レコードを取得後、each do で条件を満足するレコードを絞り込む場合は 以下のようになります。 def search_price products = Product.all ・・・@をとり、ローカル変数にする @products = Array.new ・・・@products を配列で定義する products.each do |product| ・・・productsに対して処理する item = product.price >= params[:price1].to_i && product.price <= params[:price2].to_i if item @products << product ・・・@products に追加する(@productではないことに注意 ) end end render :action => 'index' end
お礼
tatsu99様 _rinです。ご教授ありがとうございます。 出来ました!しかもシンプルなコードで書いてくださりありがとうございました。 教えてくださったコードを参考に、金額入力欄でどちらかが空白だった場合のコードも書けました。ありがとうございます。 def search_price @products = Product.where('price >=? AND price <=?', params[:price1],params[:price2]) @products = Product.where('price >=?', params[:price1]) if params[:price2].blank? @products = Product.where('price <=?', params[:price2]) if params[:price1].blank? render :action => 'index' end これにメーカーやカテゴリを含めた検索機能を応用で実装してみたいのですが、再度ご質問させていただいてもよろしいでしょうか? 絞込み検索内容 ========== ・メーカー (チェックボックス式) ・カテゴリ (チェックボックス式) ・金額指定 ========== 上記のように、絞り込み条件で、メーカーやカテゴリを選択してから、金額指定があれば、金額指定も含めて 検索結果を実装する事はできますか? ユーザーに押してもらうボタンはひとつにする形にしたいのですが、 def checkはgetで def search_priceはpostなので、 ややこしくなってしまい…^^; 再度ご教授いただければ幸いです。 ==================== views: ==================== <p>条件検索(複数選択可)</p> <%= form_tag ({:controller => :products, :action => :check }), {:method => :get} do %> <p>メーカーから探す</p> <% Maker.all.each do |maker|%> <%= check_box_tag "maker_id[]", maker.id, (params[:maker_id].include?(maker.id.to_s) if params[:maker_id]) %> <%= maker.maker_name %><br /> <% end %> <p>カテゴリから探す</p> <% Category.all.each do |c| %> <%= check_box_tag "category_id[]", c.id, (params[:category_id].include?(c.id.to_s) if params[:category_id]) %> <%= c.name %><br /> <% end %><br /> <%= submit_tag "検索"%> #このボタンを外してひとつのボタンにしたいです。 <% end %> <p>金額を指定して絞り込む</p> <%= form_tag ({:controller => :products, :action => :search_price }), {:method => :post} do %> <%= text_field_tag "price1",(params[:price1] if params[:price1]) %> ~ <%= text_field_tag "price2",(params[:price2] if params[:price2]) %> <%= submit_tag "検索"%> <% end %> ==================== products_controller.rb ==================== def check @product = Product.all if params[:maker_id] && params[:category_id] # 両方選択された場合 @products = Product.where(:category_id => params[:category_id], :maker_id => params[:maker_id] ) elsif params[:maker_id] #makerが選択された場合 @products = Product.where(:maker_id => params[:maker_id]) if params[:maker_id] elsif params[:category_id] #カテゴリが選択された場合 @products = Product.where(:category_id => params[:category_id]) if params[:category_id] elsif params[:maker_id] == nil && params[:category_id] == nil #両方ともチェックがなかった場合 @products = Product.all end render :action => 'check' end def search_price @products = Product.where('price >=? AND price <=?', params[:price1],params[:price2]) @products = Product.where('price >=?', params[:price1]) if params[:price2].blank? @products = Product.where('price <=?', params[:price2]) if params[:price1].blank? render :action => 'index' end コードがややこしくてすみません^^; どうぞよろしくお願い致します。