Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do my Rails 2 routes have query strings?

I sometimes need to pass additional parameters to a page via the URL. I did this in the past with a couple of generic placeholders in the routes file, which I call "genus" and "species". This used to work, but now it has started producing URLs with query strings.

The Rails version is 2.3.8.

The routes file is:

ActionController::Routing::Routes.draw do |map|
  map.root :controller => 'main', :action => 'index'
  map.connect ':controller', :action => 'index'
  map.connect ':controller/:action'
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:genus/:id'
  map.connect ':controller/:action/:genus/:species/:id'
end

The index page is:

<p>
<%= url_for :controller => 'main', :action => 'test', :genus => 42, :id => 1 %>
</p>

The test page is

<p>
<%= params.inspect -%>
</p>

The index page shows /main/test?genus=42&id=1 where I would have expected /main/test/42/1.

However, if I go to /main/test/42/1 then I see the correct parameters:

{"controller"=>"main", "action"=>"test", "genus"=>"42", "id"=>"1"}

Any ideas what I'm doing wrong?

like image 947
Graham Avatar asked Jan 27 '26 13:01

Graham


1 Answers

Your routes are upside-down; you want more-specific routes first, and more generic routes later. Rails will take the first route it can use to match a given set of parameters.

ActionController::Routing::Routes.draw do |map|
  map.connect ':controller/:action/:genus/:species/:id'
  map.connect ':controller/:action/:genus/:id'
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action'
  map.connect ':controller', :action => 'index'
  map.root :controller => 'main', :action => 'index'
end

That said, you could use named routes for this really easily.

ActionController::Routing::Routes.draw do |map|
  map.with_options(:path_prefix => ":controller/:action") do |con|
    con.species ":genus/:species/:id"
    con.genus   ":genus/:id"
    con.connect ":id"
    con.connect ""
  end   
end

Which gets you the following routes:

species /:controller/:action/:genus/:species/:id
  genus /:controller/:action/:genus/:id
        /:controller/:action/:id
        /:controller/:action

Then, you could just use:

<%=genus_path("main", "test", 42, 1) %>

To get:

"/main/test/42/1"
like image 179
Chris Heald Avatar answered Jan 30 '26 02:01

Chris Heald



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!