Anyone who explores Devise in their rails app will find that all the generated routes fall under a single path. Since most people choose the User model for saving user information, devise will put all these methods under /users/
rake routes new_user_session GET /users/sign_in(.:format) {:action=>"new", :controller=>"devise/sessions"} user_session POST /users/sign_in(.:format) {:action=>"create", :controller=>"devise/sessions"} destroy_user_session DELETE /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"} user_password POST /users/password(.:format) {:action=>"create", :controller=>"devise/passwords"} new_user_password GET /users/password/new(.:format) {:action=>"new", :controller=>"devise/passwords"} edit_user_password GET /users/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"} PUT /users/password(.:format) {:action=>"update", :controller=>"devise/passwords"} cancel_user_registration GET /users/cancel(.:format) {:action=>"cancel", :controller=>"devise/registrations"} user_registration POST /users(.:format) {:action=>"create", :controller=>"devise/registrations"} new_user_registration GET /users/sign_up(.:format) {:action=>"new", :controller=>"devise/registrations"} edit_user_registration GET /users/edit(.:format) {:action=>"edit", :controller=>"devise/registrations"} PUT /users(.:format) {:action=>"update", :controller=>"devise/registrations"} DELETE /users(.:format) {:action=>"destroy", :controller=>"devise/registrations"} user_unlock POST /users/unlock(.:format) {:action=>"create", :controller=>"devise/unlocks"} new_user_unlock GET /users/unlock/new(.:format) {:action=>"new", :controller=>"devise/unlocks"} GET /users/unlock(.:format) {:action=>"show", :controller=>"devise/unlocks"}
Looking at this, I wanted to customize some of the routes so they are located elsewhere in my application. eg. Move the /users/sign_in to /login and /users/sign_up to /signup
Devise and rails routes offers a few methods of doing this which are mentioned on the Devise wiki pages, but the problem I ran into was how the registration controller was mapping over top of the users controller routes.
user_registration POST /users(.:format) {:action=>"create", :controller=>"devise/registrations"} new_user_registration GET /users/sign_up(.:format) {:action=>"new", :controller=>"devise/registrations"} edit_user_registration GET /users/edit(.:format) {:action=>"edit", :controller=>"devise/registrations"} PUT /users(.:format) {:action=>"update", :controller=>"devise/registrations"} DELETE /users(.:format) {:action=>"destroy", :controller=>"devise/registrations"} user_unlock POST /users/unlock(.:format) {:action=>"create", :controller=>"devise/unlocks"}
I would like new_user_registration to point to /signup, and user_registration to /signup too. This is cause when the form is submitted, and an error occurs we want the use to remain on the /signup URL. After some help from this post on google groups:
http://groups.google.com/group/plataformatec-devise/browse_thread/thread/cfa98fd217d558e6
I ended up with these devise routes: /login, /logout, and /signup and it puts some of the registration routes under /register, thereby leaving the user actions for my users controller and not for devise. Pretty now.
devise_for :user, :path => '', :path_names => { :sign_in => 'login', :sign_out => 'logout'}, :skip => [:registration] do scope :controller => 'devise/registrations' do get :cancel, :path => 'users/cancel', :as => :cancel_user_registration post :create, :path => 'signup', :as => :user_registration get :new, :path => 'signup' , :as => :new_user_registration get :edit, :path => 'users/edit', :as => :edit_user_registration put :update, :path => 'users/edit', :as => :update_user_registration delete :destroy, :path => 'users' end end
rake routes cancel_user_registration GET /users/cancel(.:format) {:action=>"cancel", :controller=>"devise/registrations"} user_registration POST /signup(.:format) {:action=>"create", :controller=>"devise/registrations"} new_user_registration GET /signup(.:format) {:action=>"new", :controller=>"devise/registrations"} edit_user_registration GET /users/edit(.:format) {:action=>"edit", :controller=>"devise/registrations"} update_user_registration PUT /users/edit(.:format) {:action=>"update", :controller=>"devise/registrations"} destroy DELETE /users(.:format) {:action=>"destroy", :controller=>"devise/registrations"} new_user_session GET /login(.:format) {:action=>"new", :controller=>"devise/sessions"} user_session POST /login(.:format) {:action=>"create", :controller=>"devise/sessions"} destroy_user_session DELETE /logout(.:format) {:action=>"destroy", :controller=>"devise/sessions"} user_password POST /password(.:format) {:action=>"create", :controller=>"devise/passwords"} new_user_password GET /password/new(.:format) {:action=>"new", :controller=>"devise/passwords"} edit_user_password GET /password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"} PUT /password(.:format) {:action=>"update", :controller=>"devise/passwords"} user_unlock POST /unlock(.:format) {:action=>"create", :controller=>"devise/unlocks"} new_user_unlock GET /unlock/new(.:format) {:action=>"new", :controller=>"devise/unlocks"} GET /unlock(.:format) {:action=>"show", :controller=>"devise/unlocks"}
Edit: A quirk with devise is that the update_user_registration uses the same action="{URL}" as user_registration no matter what is defined in the routes. This causes the action for update_user_registration to send the put to /signup when we want it to go to /user/edit. The solution is to edit the registration/edit.html.erb and change
:url => registration_path(resource_name)
to:url => :update_user_registration
.
No comments:
Post a Comment