Reputation: 1920
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
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
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