ruby-on-railsrubydeviserails-routing

Conflicting Devise and restful controller routes | Rails 5.2


I'm working on a Rails 5.2 project that uses Devise to manage a User model. I want users to be able to sign themselves up, and allow administrators to create accounts on their behalf. I've set up the User model with Devise, and generated scoped controllers (and views) for the resource. This covers the self-signup aspect, and to cover the administrator-initiated sign-up, I've created a users_controller as a standard restful controller, and in the routes, set up a resources route respectively. This seems to work for everything except the users#create action route conflicts with the route created by the devise_for for users/registrations#create (see generated routes below). This causes users#new form submissions to be incorrectly handled by the Devise users/registrations#create instead of users#create.

What would be the best way of making the *#create routes unique?

routes.rb

Rails.application.routes.draw do
  devise_for :users, controllers: { sessions: 'users/sessions', registrations: 'users/registrations' }

  resources :users
end

Generated Routes

        new_user_session GET    /users/sign_in(.:format)        users/sessions#new
            user_session POST   /users/sign_in(.:format)        users/sessions#create
    destroy_user_session DELETE /users/sign_out(.:format)       users/sessions#destroy
       new_user_password GET    /users/password/new(.:format)   devise/passwords#new
      edit_user_password GET    /users/password/edit(.:format)  devise/passwords#edit
           user_password PATCH  /users/password(.:format)       devise/passwords#update
                         PUT    /users/password(.:format)       devise/passwords#update
                         POST   /users/password(.:format)       devise/passwords#create
cancel_user_registration GET    /users/cancel(.:format)         users/registrations#cancel
   new_user_registration GET    /users/sign_up(.:format)        users/registrations#new
  edit_user_registration GET    /users/edit(.:format)           users/registrations#edit
       user_registration PATCH  /users(.:format)                users/registrations#update
                         PUT    /users(.:format)                users/registrations#update
                         DELETE /users(.:format)                users/registrations#destroy
                         POST   /users(.:format)                users/registrations#create
---
                   users GET    /users(.:format)                users#index
                         POST   /users(.:format)                users#create
                new_user GET    /users/new(.:format)            users#new
               edit_user GET    /users/:id/edit(.:format)       users#edit
                    user GET    /users/:id(.:format)            users#show
                         PATCH  /users/:id(.:format)            users#update
                         PUT    /users/:id(.:format)            users#update
                         DELETE /users/:id(.:format)            users#destroy

Solution

  • Something like this

    devise_for :users, controllers: { sessions: 'users/sessions', registrations: 'users/registrations' }
    
    devise_scope :user do
      post   '/users/create'  => 'users#create',  as: :create_user
      get   '/users'  => 'users#index',  as: :list_users
      get   '/users/:id' => 'users#show', as: :show_user
    end
    

    or you can skip create action while defining resources :users, except: :create and make use of registrations_controller create.