So for your route, the :id
is present, right? That's why you have to provide the id when you generate your route.
You could overwrite the route so that it contains no :id
, or set :id
as optional (use (:id)
, and then append your id as param to send.
However I haven't used remote_function before :D
===== UPDATE =====
So I'm really not familiar with remote_function as I seldom use the built-in prototype, but jquery.
It seems like you are giving a list of city id for choose, then pass the id to the sever to get the city, and display it on the page.
The following is just an example, might not suit you case:
Define the route:
map.ajax_show_city "/cities/:id", :controller => "cities", :action => "show"
In CitiesController
def show
@city = City.find(params[:id])
respond_to do |format|
format.html #if you don't like, you could delete this line
format.js # auto call cities/show.js.erb
end
end
In cities/show.js.erb
jQuery("#the_place_you_want").append("<%= javascript_escape(render(:partial=>@city)) %>");
The render would use cities/_city.html.erb to give the city html code
<%= select_tag "cities", cities_options(with_id_as_the_option_value), :onchange => "show_city(this, '#{url_for(ajax_show_city_path)}')" %>
# This will generate something like:
<select name="cities" id="cities" onchange="show_city(this, '/cities')"> # note the path generated
<option value="1">City 1</option>
<option value="2">City 2</option>
</select>
The js function needed:
function show_city(select, link) { # sorry for using jQuery
$.post(link + "/" + retrieve_option_value(select), "", null, "script");
# $.post(link_to_post, addintional_data, handling_function_after_success, request_type)
# This would post to /cities/2 with no any params added.
# Due the the request type being set to script, the returned data would be treated as javascript and executed. So no handling function is needed (that's why null)
}
function retrieve_option_value(select) {
$(select).children(":selected").val(); # just get the selected option's value
}
That's all.
So if the js is switched off, the user could still press the submit button (use js to hide or detach the button) and get proper result! Adding js is just adding more fancy things.
Of course, I agree that almost everyone won't turn off their js support. But it's the accessibility to the disables.
=====
It's quite tricky that for resource's show path, it seems you must provide an id
in order to generate the path without error.
you could test the routes:
map.connect "/test", :controller => "cities", :action => "test" # for test only
map.resources :cities
map.other "/cities/show/:id", :controller => "cities", :action => "show", :method => :get
def test
render :text => url_for(city_path) # ambiguous routes error
render :text => url_for(city_path(0) # gives /cities/0
render :text => url_for(other_path) # gives /cities
render :text => url_for(other_path(0)) # gives /cities/0
end
A workaround for your way is to generate /cities/0
and in runtime use js to replace 0
by your selected id.