Neil Wheatley
Neil Wheatley

Reputation: 71

Customising Devise registration edit/update routes and views

I've just started using Devise and I've made some customisations:

Everything works great except the edit_user_registration stuff (the view where users can change their email and password or delete their account).

This is what I have for registrations in config/routes.rb (parts not related to registrations controller are omitted):

devise_for  :users, skip: [:registrations]

as :user do

  # joining
  get   '/register' => 'users/registrations#new', as: 'new_user_registration'
  post  '/register' => 'users/registrations#create', as: 'user_registration'

  scope '/user' do

  # settings & cancellation
  get '/cancel'   => 'users/registrations#cancel', as: 'cancel_user_registration'
  get '/settings' => 'users/registrations#edit', as: 'edit_user_registration'
  patch '/settings' => 'users/registrations#update'

  # account deletion
  delete '' => 'users/registrations#destroy'

end

I changed put to patch because I'm using Rails 4 (is this correct?).

This is my form_for tag in views/users/registrations/edit.html.erb:

<%= form_for(resource,  as: resource_name,
                            url: registration_path(resource_name),
                            html: { method: :patch }) do |f| %>

When I try to update settings for a user with the above code, I get a 500 internal server error. Submitting the form attempts to load /register (my signup page), which is surely not right. (I think this is the heart of the problem but I don't understand how to fix it as I'm quite a beginner.)

When I try to update settings for a user with the original put method (instead of patch), I get the same problem.

My development web server says:

ActionController::RoutingError (No route matches [PUT] "/register"):

Thanks in advance.

EDIT: Added rake routes output below.

                  Prefix Verb   URI Pattern                     Controller#Action
   new_user_registration GET    /register(.:format)             users/registrations#new
       user_registration POST   /register(.:format)             users/registrations#create
cancel_user_registration GET    /user/cancel(.:format)          users/registrations#cancel
  edit_user_registration GET    /user/settings(.:format)        users/registrations#edit
                settings PUT    /user/settings(.:format)        users/registrations#update
                         DELETE /user(.:format)                 users/registrations#destroy

EDIT 2: This is what rakes routes looks like when I remove custom routes and let Devise handle registrations views etc.:

                  Prefix Verb   URI Pattern                     Controller#Action
   new_user_registration GET    /users/sign_up(.:format)        devise/registrations#new
       user_registration POST   /users(.:format)                devise/registrations#create
cancel_user_registration GET    /users/cancel(.:format)         devise/registrations#cancel
  edit_user_registration GET    /users/edit(.:format)           devise/registrations#edit
                         PATCH  /users(.:format)                devise/registrations#update
                         PUT    /users(.:format)                devise/registrations#update
                         DELETE /users(.:format)                devise/registrations#destroy

WORKING:

routes.rb:

get 'settings'  => 'users/registrations#edit', as: 'edit_user_registration'
put 'settings/:id' => 'users/registrations#update', as: 'update_user_registration'

edit.html.erb:

<%= form_for(resource,  as: resource_name,
                        url: update_user_registration_path(resource_name),
                        html: { method: :put }) do |f| %>

Upvotes: 2

Views: 3884

Answers (1)

Kristj&#225;n
Kristj&#225;n

Reputation: 18803

The problem is that registration_path is submitting the form to /register, which is for new users, but you're trying to edit an existing User object, so you need to submit to the correct update path. By default, that's the PUT /users/:id you see when you remove your configurations.

It looks like your customizations have set the User update path to PUT /user/settings, so try url: settings_path. You're aiming for the users/registrations#update action seen in this row:

            Prefix Verb   URI Pattern                     Controller#Action
          settings PUT    /user/settings(.:format)        users/registrations#update

Upvotes: 1

Related Questions