简体   繁体   中英

devise with existing model creates overlapping routes

It's the first time i try to add devise authenticability to an already existing model.
I've reproduced the problem in a very essential example (tested on ruby 2.1.1, rails 4.1.5, devise 3.3.0).

$ rails new devise_sample1 --database=postgresql

then i've create the model:

$ rails g scaffold custom_user name surname date_of_birth:date

Bear in mind that my model is called 'custom_user'.

Then i've tuned db configuration and i've created and migrated the db.

Now let's add devise, adding to the Gemfile the line:

gem 'devise'

As a first step, devise requires installation:

$ rails g devise:install

That in turn requires to add to config/environments/development.rb the following line:

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

At this point i'm ready to push devise into my existing model:

rails generate devise custom_user

So far so good; migrate again and start the server and connect to

http://localhost:3000/customer_users 

via browser; push the button 'new customer_user".

Not surprisingly, here is what i get, that is the result of my scaffold:

在此处输入图片说明

But now let's push the button "Create Custom user".

Here is what we'll get :

在此处输入图片说明

Amazing . From my custom_user form, i end up to the registration form of devise. That means that routes are well inter-mixed.

So let's have a look at them:

GET    /custom_users/sign_in(.:format)       devise/sessions#new
POST   /custom_users/sign_in(.:format)       devise/sessions#create
DELETE /custom_users/sign_out(.:format)      devise/sessions#destroy
POST   /custom_users/password(.:format)      devise/passwords#create
... (other password routes)
GET    /custom_users/cancel(.:format)        devise/registrations#cancel
POST   /custom_users(.:format)               devise/registrations#create
GET    /custom_users/sign_up(.:format)       devise/registrations#new
GET    /custom_users/edit(.:format)          devise/registrations#edit
PATCH  /custom_users(.:format)               devise/registrations#update
PUT    /custom_users(.:format)               devise/registrations#update
DELETE /custom_users(.:format)               devise/registrations#destroy
GET    /custom_users(.:format)               custom_users#index
POST   /custom_users(.:format)               custom_users#create
GET    /custom_users/new(.:format)           custom_users#new
GET    /custom_users/:id/edit(.:format)      custom_users#edit
GET    /custom_users/:id(.:format)           custom_users#show
PATCH  /custom_users/:id(.:format)           custom_users#update
PUT    /custom_users/:id(.:format)           custom_users#update
DELETE /custom_users/:id(.:format)           custom_users#destroy

So, the browser hits the "new" action then submits to the "create" action:

POST   /custom_users(.:format)               custom_users#create

that happens to be the very same route of:

POST   /custom_users(.:format)               devise/registrations#create

The other routes seem not to overlap by chance rather than by design, so i've two questions.

1) is this the way of integrating devise on an existing model or have i lost some foundamental step?

2) if this is the way, how am i supposed to fix it ?

Your custom_user creation should happen through devise registration controller. To create/register new custom_user using devise use new_custom_user_registration_path (which will route you to /custom_users/sign_up ) instead of new_custom_user_path ( /custom_users/new ). Even if you want to edit custom_user profile, use edit_custom_user_registration_path instead of edit_custom_user_path .

If you want to add other custom_user attributes to sign_up form you can customize the devise views. See how to customize devise views

You could use an other routename for devise. I add my own controller additionally

rails generate devise:install
rails generate devise existingmodel

rake db:migrate

rails generate devise:controllers auth

in config/routes.rb

devise_for :users, class_name: :ExistingModel ,controllers: {
                   sessions: 'auth/sessions'
               }

it works in my environment...

Change

resources :custom_users

to another path:

resources :custom_users, path: 'custom_user'

This way, Devise will use /custom_users
while Scaffolded views will use /custom_user

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM