This is somewhat difficult to answer because you don't tell us much
about your solution. Do you want to use ajax or do a full postback?
What does the markup look like? You'll need to supply more of these
details in the future.
Here's one solution (untested). I'll explain as I go:
items/index.html.erb
<fieldset><legend>Choose category</legend>
<%= select :item, :category_id, [... however you select
categories ...] %>
<%= observe_field 'item_category_id', :url=>items_path %>
</fieldset>
<h2>Items</h2>
<ul id="item_list">
<%= render :partial => 'items' %>
</ul>
items/_items.html.erb
<% @items.each do |item| %>
<% content_tag_for :li, item, item.name %>
<% end %>
The combination of the two forms above should work together to render
your initial list as you already have it coded. The items will be
placed into an unordered list. The key is the "observe_field" call
which adds some javascript that will look for changes in the select
field (drop-down) and send them back to the server automatically. I
am suggesting that you send this back to the same #index action to
keep the public interface small.
class ItemsController < ApplicationController
def index
find_options=>{:order=>:name}
find_options.merge :conditions=>{:category_id=>params[:value]} if
params[:value]
@items = Item.find(:all, find_options)
respond_to do |format|
format.html # index.html.erb
format.js { render(:update){|page| page.replace_html
'item_list', :partial=>'items'}
end
end
end
The controller action is a little different. First, it creates a hash
with :order=>:name to make sure the items are sorted by name. Next,
it adds :conditions=>{:category_id=>params[:value]} to it if
supplied. This basically says that if a category was supplied then
limit the find to that category, otherwise return all the items.
The format.js line is also new. The observe_field is submitting the
request via ajax and is expecting a javascript (js) response so the
effect of the line is to render that back. Specifically, the code
renders back a small javascript that tells the page to find the
element named 'items_list' (the <ul>) and replace its contents with
the result of rebuilding the _items partial with a restricted
collection of items.
It's worth pointing out that the render(:update) code could be handled
differently. You could create an index.js.rjs file to handle that.
If you do, then the render(:update) part is handled for you by the
framework -- you'll only need to have the page.replace_html line in
the file. That may be an advantage if you find that you need to do
more work on the page than just rebuild the list. Personally I do not
mind putting one or two lines of rjs code in the controller though it
*is* mixing view and controller logic in one place. Purists would
never do that, even for one line.
Good luck.