I have recently been working on a simple list action and view that will allow a user to filter the objects that are selected by changing a category value in a <select> control.
In this case, the resources being listed are restaurants. The view also contains a list of all restaurant categories, which defaults to a selection of "All Categories", that will allow them to filter the restaurants displayed by category.
I have a working implementation, however, it feels like a bit of a hack. In the view, I am using the form_for and collection_select helpers, because they handle auto-selecting the appropriate value and don't require me to assemble an options hash. The part that feels like a hack to me is that in order to get the auto-selection to work, I am creating a Category model object in the controller, and assigning the id value that was submitted through the form as the object's "id" property. Also, I have to explicitly set the "name" property in the htmlOptions hash, so that the field gets submitted as params[:category_id] rather than params[:category_id].
I am new to Rails, and I wanted to see if anyone felt there was a cleaner way for me to implement this functionality. Anyhow, here's the code. Any suggestions would be greatly appreciated:
#** Controller **# def index (@category = Category.new()).id = params[:category_id]
if (!@category.id.nil?) @restaurants = Restaurant.find_all_by_category_id(@category.id) else @restaurants = Restaurant.find(:all) end
respond_to do |format| format.html { @categories = Category.find(:all) } # index.html.erb format.xml { render :xml => @restaurants } end end
#** View (index.rhtml) **# <% form_for( :category, :html => {:method => :get}) do |f| %> <%= f.collection_select( :id, @categories, :id, :name, {:include_blank => 'All Categories'}, {:onchange => 'this.form.submit();', :name => 'category_id'} ) %> <% end %>
Lastly, I was wondering if it would it make more sense to move the category selection form to a partial, rather than embed it directly in index.rhtml with these rest of the code (which is not shown above)?
Thanks for the help,
Justin Holzer