Using named routes with parameters and form_tag

Stewart Johnson picture Stewart Johnson · Jan 30, 2010 · Viewed 7.8k times · Source

I'm trying to create a simple search form in Rails, but I think I'm missing something.

I have a named route for search:

map.search ":first_name/:last_name", :controller => "home", :action => "search"

I'm trying to use that in my search form:

<% form_tag(search_path, :method => 'get') do %>
  <%= text_field_tag(:first_name) %>
  <%= text_field_tag(:last_name) %>
  <%= submit_tag("Search") %>
<% end %>

But when I load up the search form I get an ActionController::RoutingError:

search_url failed to generate from {:action=>"search", :controller=>"home"} - you may have ambiguous routes, or you may need to supply additional parameters for this route. content_url has the following required parameters: [:first_name, :last_name] - are they all satisfied?

What am I missing? I thought the fields defined in my form would be automatically linked up with my route parameters. :-/

Update:

I understand that search_path is generated before the form is displayed now, so it can't be updated. Obvious in hindsight!

I changed my routes:

map.search 'search', :controller => "home", :action => "search"
map.name ':first_name/:last_name', :controller => "home", :action => "name"

And now the search action just does:

def search
  redirect_to name_path(params)
end

It all works a treat! The main goal here was getting that URL from the name named route as result of doing a search. Thanks guys!

Answer

klew picture klew · Jan 30, 2010

form_for generates form and it has to have specified all parameters that are needed to create search_path, so it should look like:

<% form_tag(search_path, :firstname => 'some_text', :lastname => 'some_text', :method => 'get') do %>

or at least something like this. HTML tag form has parameter action='/some/url' and that's why you have to specify all parameters for search_path. But the above example won't work as you expected.

So what you can do?

  1. Create empty form that has action='/' and with js replace it with content of your input text fields before submitting.

  2. Create another route, on example /search that recives parameters from submit and then redirects to correct path.

Probably there is also some better ways to do it ;)