2011-09-24 112 views
0

我試圖通過下拉菜單(位置)和一組複選框(類別)篩選產品的索引頁,但不是很成功。我可以通過下拉菜單篩選位置或類別。我也可以將這兩個下拉列表合併成一個表格,但是如果我無法將工作解決方案分配給兩個單獨的表格。Rails:通過下拉菜單和複選框篩選索引

我想實現的是提交onchange的位置的下拉列表以及我希望作爲帶有過濾按鈕的複選框的類別。

我此刻的代碼提供下拉和複選框,但也存在一些問題:

  • 複選框列出所有類別,但是當我篩選基於這些的PARAMS作爲一個數組傳遞但沒有產品在視圖返回
  • 每當我按類別篩選我失去了以前的位置選擇

下面是相關代碼:

產品型號

.... 
has_many :categorizations 
has_many :categories, :through => :categorizations 
has_many :localizations 
has_many :locations, :through => :localizations 
class Product < ActiveRecord::Base 
default_scope :order => 'end_date' 
scope :not_expired, where('end_date > ?', Time.now) 
scope :location, lambda { |*location_id| {:include => :locations, :conditions => ["locations.id = ?", location_id]} } 
scope :category, lambda { |*category_id| {:include => :categories, :conditions => ["categories.id = ?", category_id]} } 
scope :unique, :group => "title" 

控制器

class LibraryController < ApplicationController 
    def index 
    if params[:location_id] && params[:category_ids] 
    @products = Product.not_expired.unique.location(params[:location_id]).category(params[:category_ids]).paginate(:page => params[:page], :per_page => 9) 
    elsif params[:category_ids] 
    @products = Product.not_expired.unique.category(params[:category_ids]).paginate(:page => params[:page], :per_page => 9) 
    elsif params[:location_id] 
    @products = Product.not_expired.unique.location(params[:location_id]).paginate(:page => params[:page], :per_page => 9) 
    else 
    @products = Product.not_expired.unique.paginate(:page => params[:page], :per_page => 9) 
    end 
    end 
end 

圖書館index.html.erb

<% if notice %> 
<p id="notice"><%= notice %></p> 
<% end %> 

     <div class="filter_options"> 

     <form class="filter_locations", method="get"> 
      <% @options = Location.all.map { |a| [ a.name, a.id ] } %> 
      <%= select_tag "location_id", options_for_select(@options), :onchange => "this.form.submit();", :include_blank => true %> 
     </form> 

     <form class="filter_categories", method="get"> 
      <% for category in Category.all %> 
      <%= check_box_tag("[category_ids][]", category.id) %> 
      <%= category.name %> 
      <% end %> 
      <input type="submit" value="Filter" /> 
     </form> 
    </div> 

我一直兜兜轉轉這個,所以任何方向是極大的讚賞。

部分回答我自己的問題我修改了庫索引,並在類別表單中使用了一個隱藏字段,它調用了location_id參數,如果它存在,這意味着我可以保留選擇後選擇的所有位置類別複選框。

進一步更新是我添加了一個檢查是否通過查詢下面的參數,更新庫index.html.erb檢查類別複選框。

最後編輯與合併@rdvdijk輸入(謝謝)

庫index.html.erb

....... 
    <%= form_tag('', :method => :get) do %> 
     <% @options = Location.all.map { |a| [ a.name, a.id ] } %> 
     <%= select_tag "location_id", options_for_select((@options), params[:location_id]), :onchange => "this.form.submit();", :include_blank => true %> 
    <% end %> 
    <%= form_tag('', :method => :get) do %> 
     <% if(params.has_key?(:location_id)) %> 
     <%= hidden_field_tag 'location_id', params[:location_id] %> 
     <% end %> 
    <% Category.all.each do |category| %> 
    <%= check_box_tag 'category_ids[]', category.id, params[:category_ids].to_s.include?(category.id_to_s) %> 
     <%= category.name %> 
    <% end %> 
    <%= submit_tag 'Filter' %> 
    <% end %> 
....... 

回答

1

你有兩種形式,我認爲這是你的問題的一部分。每當您在第一個表格中更改位置時,只有location_id將被髮送到您的控制器index操作。每當您選擇一個類別並提交第二個表格時,只有category_ids將被髮送到您的控制器index的操作。

使用一種形式看看會發生什麼。它至少應該爲單個提交進行過濾工作。

我看到的第二個問題是,您不選擇所選的位置,或檢查所選的類別。

看看options_for_selectcheck_box_tag的文檔來解決這個問題。

+0

當兩種選擇都在一種形式但我不能獨立選擇(位置或類別)時,我可以使選擇工作。我現在在類別選擇中使用一個隱藏字段,如果該字段存在,它允許我先設置位置,然後再過濾類別。我編輯了我的問題以顯示修改。我不確定我是否遵循了您提出的第二個問題,但我會查看該文檔。謝謝 – shane

+0

所以你的問題歸結爲:你有兩個過濾器。當您更改第一個時,應該應用兩個過濾器,並且只有第二個過濾器在更改時應用。我理解正確嗎? – rdvdijk

+0

按照你的建議,我意識到我沒有選擇任何形式的狀態後,我做了選擇,所以我添加了一些查詢,設置過濾器的狀態基於參數。我對原始問題做了一些更新。因此,過濾器的工作方式應該如下:使用任一選擇自行提交該過濾器,除非在提交兩者並保留狀態的位置之後選擇了類別。所以我最後的問題是,雖然category_ids作爲數組傳遞,但數據庫查詢並未返回任何產品。感謝你目前的幫助。 – shane

0

在我的情況下,產品belongs_to:類別和類別has_many:產品,我修改categories.id到category_id,它的工作原理!

scope :category, lambda { |*category_id| {:include => :categories, :conditions => ["category_id = ?", category_id]} } 
相關問題