Rails 4 upgrade gotcha #1 (routes definition)
When I upgraded from Rails 3 to 4, I ran into some problems which I will share here.
If you use Sorcery or Authlogic for authorization, you create your login and logout routes by yourself. I found this code in my routes.rb file, where the /login
path is used for GET
and POST
requests and can be refered to as login_path
.
# Rails 3
match '/login' => 'sessions#new', as: :login, via: 'get'
match '/login' => 'sessions#create', as: :login, via: 'post'
While this works well with Rails 3, you get the following error with Rails 4:
/gems/actionpack-4.0.0/lib/action_dispatch/routing/route_set.rb:409:in `add_route': Invalid route name, already in use: 'login' (ArgumentError)
You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restrict the routes created with `resources` as explained here: ...
How to fix this? Just use get
and post
instead of match
to describe the routes and remove the as
option.
# Rails 4
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
This looks shorter and nicer, plus both routes are still available as login_path
.
So far so good, but how does this work with routes containing variables? Like here:
# Rails 3
match '/signup/:plan' => 'accounts#create', as: :signup, via: 'post'
match '/signup/:plan' => 'accounts#new', as: :signup, via: 'get'
The solution: just use get
and post
like above. To make it available as a named route, you have to set the as
option for the first route. The second will be automatically available under the same name.
# Rails 4
get 'signup/:plan' => 'accounts#new', as: :signup
post 'signup/:plan' => 'accounts#create'