T0ny lombardi
T0ny lombardi

Reputation: 1920

Routing in rails 4

I am upgrading an app from 3.2.4 to Rails 4 In my previous version i used:

match ':controller(/:action(/:id))(.:format)'
match ':controller(/search)(.:format)' => ':controller#search' 

Now im getting an error

C:/Ruby193/lib/ruby/gems/1.9.1/gems/actionpack-4.0.0/lib/action_dispatch/routing/mapper.rb:239:in `default_controller_and_action': 
':controller' is not a supported controller name. This can lead to potential routing problems. See http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use (ArgumentError)

I have about 10 to 15 different controllers that all use search. Is there away I can use a similar code instead of writing each controller to match controller#search ?

Upvotes: 0

Views: 474

Answers (2)

user3356885
user3356885

Reputation: 401

Second line is redundant because

match ':controller(/search)(.:format)' => ':controller#search'

covered in

match ':controller(/:action)(.:format)'

that is basically your first line route definition.

From Rails documentation in http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html

Rails 4.0 requires that routes using match must specify the request method.

So your routes should look like this

match ':controller(/:action(/:id))(.:format)', via: :get

or this

get ':controller(/:action(/:id))(.:format)'

Upvotes: 0

Peter Brown
Peter Brown

Reputation: 51717

I would just loop over all the controllers in an array and define each one dynamically like this:

%w(controller1 controller2 controller3).each do |controller_name|
  match "#{controller_name}(/search)(.:format)" => "#{controller_name}#search", via: :get
end

Note that you now need to add the via option that was not previously required. I assumed your search was via a GET request, but it might be via POST instead.

An added benefit of this approach is now if you inspect your routes, you will see exactly which ones are defined, and there is no guessing:

GET        /controller1(/search)(.:format)         controller1#search
GET        /controller2(/search)(.:format)         controller2#search
GET        /controller3(/search)(.:format)         controller3#search

Upvotes: 2

Related Questions