I have a Rails app, v4, and just need ot modify some "old" code - I need to add some attributes to the admin model.
When I tried to add a new admin user and set to the browser "/admins/sign_up", I got an error message that the route doesn't exist.
Okay, so I checked all the Devise routes:
new_admin_session GET /admins/sign_in(.:format) devise/sessions#new
admin_session POST /admins/sign_in(.:format) devise/sessions#create
destroy_admin_session DELETE /admins/admin_logout(.:format) devise/sessions#destroy
admin_password POST /admins/password(.:format) devise/passwords#create
new_admin_password GET /admins/password/new(.:format) devise/passwords#new
edit_admin_password GET /admins/password/edit(.:format) devise/passwords#edit
PATCH /admins/password(.:format) devise/passwords#update
PUT /admins/password(.:format) devise/passwords#update
new_user_session GET /users/login(.:format) devise/sessions#new
user_session POST /users/login(.:format) devise/sessions#create
destroy_user_session DELETE /users/logout(.:format) devise/sessions#destroy
user_password POST /users/secret(.:format) devise/passwords#create
new_user_password GET /users/secret/new(.:format) devise/passwords#new
edit_user_password GET /users/secret/edit(.:format) devise/passwords#edit
PATCH /users/secret(.:format) devise/passwords#update
PUT /users/secret(.:format) devise/passwords#update
How is possible that the routes for a new admin sign up is missing? Did I miss something?
Anyway, how to add this missing route?
When I look to the views, I see that in admins/registrations/ is new.html.erb and there's a sign up form for a new admin.
How to display (under which URL) form and use it?
Thank you in advance.
EDIT: Routes
devise_for :admins, :path_names => {:sign_out => 'admin_logout'}
devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret',
:confirmation => 'verification', :unlock => 'unlock', :registration => 'register',
:sign_up => 'signup' }, :controllers => {:omniauth_callbacks => "omniauth_callbacks", :registrations => "registrations"}
You can add the missing /admins/sign_up route like the following:
devise_for :admins do
get '/admins/sign_up' => 'devise/registrations#new'
end
This generates this route:
new_admin_registration GET /admins/sign_up(.:format) devise/registrations#new
and should fix your problem.
Update:
Remove this from your current routes file:
devise_for :admins, :path_names => {:sign_out => 'admin_logout'}
Add this to your routes file:
devise_for :admins do
get '/admins/sign_up' => 'devise/registrations#new'
end
Related
This question already has an answer here:
Customize Devise pathnames
(1 answer)
Closed 3 years ago.
When I run rake routes | grep sessions I'm getting duplicate entries despite already having my own settings.
Here's my output: (these aren't all of the duplicates btw.)
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
login GET /login(.:format) devise/sessions#new
POST /login(.:format) devise/sessions#create
logout DELETE /logout(.:format) devise/sessions#destroy
The top three are the default routing settings from Devise and the bottom three are the ones I've added in config/routes.rb.
Here is sample of my config/routes.rb file pertaining to Devise:
Rails.application.routes.draw do
root to: 'pages#index'
# Users
devise_for :users, controllers: {
# I override a few actions in my own controller so I needed this
registrations: 'users/registrations',
}
# FYI: as is an alias for devise_scope
as :user do
# devise/sessions_controller handlers
get 'login', to: 'devise/sessions#new'
post 'login', to: 'devise/sessions#create'
delete 'logout', to: 'devise/sessions#destroy'
#.... other registrations controller settings that are also getting duplicated
end
# .... all my other application routes
end
I guess what I'm asking is, how to I suppress the default routes from Devise since I've created my own? If you need more of my rake routes output or config/routes.rb file I can submit the whole thing.
EDIT:
Ok looks like I need to add a :path_names hash to my devise_for :users block. From https://devhints.io/devise, I can see a selection of options for the paths at the end of the page. Also removing the :path option altogether gives me an unaliased version which matches what I wanted.
Here's what I had to do to get it (mostly) right:
devise_for :users, :path => '',
:path_names => {
:sign_in => 'sign-in',
:sign_out => 'sign-out',
:password => '',
:confirmation => 'verification',
:unlock => 'unblock',
:registration => 'register',
:sign_up => '' },
# ignore this, changing this probably wont fix anything plus I need it.
controllers: {
registrations: 'users/registrations'
}
Its not totally perfect so Ill give the answer to anyone who can show me how to get:
root GET / pages#index
new_user_session GET /sign-in(.:format) devise/sessions#new
user_session POST /sign-in(.:format) devise/sessions#create
destroy_user_session DELETE /sign-out(.:format) devise/sessions#destroy
cancel_user_registration GET /register/cancel(.:format) users/registrations#cancel
new_user_registration GET /register(.:format) users/registrations#new
edit_user_registration GET /register/edit(.:format) users/registrations#edit
user_registration PATCH /register(.:format) users/registrations#update
PUT /register(.:format) users/registrations#update
DELETE /register(.:format) users/registrations#destroy
POST /register(.:format) users/registrations#create
password GET /password(.:format) devise/passwords#new
reset_password GET /reset-password(.:format) devise/passwords#edit
PATCH /reset-password(.:format) devise/passwords#update
PUT /reset-password(.:format) devise/passwords#update
POST /password(.:format) devise/passwords#create
I DONT WANT THE FOLLOWING IN MY ROUTES:
new_user_password GET /new(.:format) devise/passwords#new
edit_user_password GET /edit(.:format) devise/passwords#edit
user_password PATCH / devise/passwords#update
PUT / devise/passwords#update
POST / devise/passwords#create
I could change :password => '' to :password => 'reset-password' but then I get these:
new_user_password GET /reset-password/new(.:format) devise/passwords#new
edit_user_password GET /reset-password/edit(.:format) devise/passwords#edit
POST /reset-password(.:format) devise/passwords#create
When what I want is this:
new_user_password GET /password(.:format) devise/passwords#new
edit_user_password GET /reset-password(.:format) devise/passwords#edit
POST /password(.:format) devise/passwords#create
Ok looks like I need to add a :path_names hash to my devise_for :users block. From https://devhints.io/devise, I can see a selection of options for the paths at the end of the page. Also removing the :path option altogether gives me an unaliased version which matches what I wanted.
EDIT:
On top of what I found (and included in my question) I also found the :skip option. Someone has already asked a similar question that I have and the perfect answer to this (telling Devise not to generate ANY of the routes I want to override) is here:
https://stackoverflow.com/a/46900434/43792
My goal is to only be able to access the sign_up page if you visit a url matching 'invite/:code', i.e. sign_up: 'invite/:code' And to keep the sign_in page with default / equivalent functionality.
I have the sign_up route working great, but sign_in is broken.
My routes.rb file contains the following code:
devise_for :users, {
# skip: [:sessions],
controllers: {
omniauth_callbacks: "users/omniauth_callbacks",
registrations: "invite",
},
path: '',
path_names: {
sign_up: 'invite/:code',
sign_in: 'sign_in'
}
}
# as :user do
# get 'sign_in', to: 'devise/sessions#new', as: :new_user_session
# post 'sign_in', to: 'devise/sessions#create', as: :user_session
# delete 'sign_out', to: 'devise/sessions#destroy', as: :destroy_user_session
# end
The commented out lines are the ones I am confused about, unsure if I need them.
When I visit /sign_in I get the following error:
No route matches {:action=>"new", :controller=>"invite"}, missing required keys: [:code]
It seems that sign_in is still trying to use my custom registrations controller or something, not sure.
My rake routes outputs this bit:
new_user_session GET /sign_in(.:format) devise/sessions#new
user_session POST /sign_in(.:format) devise/sessions#create
Here is more rake routes stuff:
new_user_session GET /sign_in(.:format) devise/sessions#new
user_session POST /sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /sign_out(.:format) devise/sessions#destroy
user_facebook_omniauth_authorize GET|POST /auth/facebook(.:format) users/omniauth_callbacks#passthru
user_facebook_omniauth_callback GET|POST /auth/facebook/callback(.:format) users/omniauth_callbacks#facebook
new_user_password GET /password/new(.:format) devise/passwords#new
edit_user_password GET /password/edit(.:format) devise/passwords#edit
user_password PATCH /password(.:format) devise/passwords#update
PUT /password(.:format) devise/passwords#update
POST /password(.:format) devise/passwords#create
cancel_user_registration GET /cancel(.:format) invite#cancel
new_user_registration GET /invite/:code(.:format) invite#new
edit_user_registration GET /edit(.:format) invite#edit
user_registration PATCH / invite#update
PUT / invite#update
DELETE / invite#destroy
POST / invite#create
I was being dumb, didn't look carefully enough at the error message. The error was coming from a partial which was calling the new_registration_path helper (sign_up) and I was not passing in code as a param.
So the solution was to change this:
new_registration_path(resource_name)
to this:
new_registration_path(resource_name, :code => 'foo')
I have added custom routes for the devise actions. this does not work when I try to go to /profile/edit or /login or /logout Here is the rake routes:
saasbook#saasbook:~/Documents/ronde$ rake routes
static_about GET /static/about(.:format) static#about
static_tour GET /static/tour(.:format) static#tour
static_home GET /static/home(.:format) static#home
static_terms_of_use GET /static/terms_of_use(.:format) static#terms_of_use
static_contact GET /static/contact(.:format) static#contact
users_profile GET /users/profile(.:format) registrations#edit
login GET /login(.:format) devise/sessions#new
logout GET /logout(.:format) devise/sessions#destroy
register GET /register(.:format) devise/registrations#new
profile_edit GET /profile/edit(.:format) devise/registrations#edit
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session GET /users/sign_out(.:format) devise/sessions#destroy
user_omniauth_authorize GET|POST /users/auth/:provider(.:format) omniauth_callbacks#passthru {:provider=>/google|facebook/}
user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) omniauth_callbacks#(?-mix:google|facebook)
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root / static#home
Here is my routes.rb file where I added the the new routes with the same controller actions for devise:
Ronde::Application.routes.draw do
get "static/about"
get "static/tour"
get "static/home"
get "static/terms_of_use"
get "static/contact"
get "/user/profile", :to => 'registrations#edit'
get "/login", :to => "devise/sessions#new" # Add a custom sign in route for user sign in
get "/logout", :to => "devise/sessions#destroy" # Add a custom sing out route for user sign out
get "/register", :to => "devise/registrations#new" # Add a Custom Route for Registrations
get "profile/edit", :to => "devise/registrations#edit"
devise_for :users, :controllers => { :omniauth_callbacks => "omniauth_callbacks" }
root to: 'static#home'
end
# :path_names => {:edit => "profile/edit", :sign_in => "login", :sign_out => "logout", :sign_up => "register" }
Then page says that and should route to the devise controller:
Routing Error
No route matches [GET] "/profile/edit"
Try running rake routes for more information on available routes.
I don't know if this right but I think you can't do that way, because Devise doesn't have any controller. Please check this question and this.
What I done usually was making another controller for Devise, or normal controller like users_controller with it own views. And register it on routes.rb like:
devise_for :users
scope "/admin" do
resources :users
end
Then when I need to open it, I called localhost:3000/admin/users
But please correct me if there anything wrong, or my way to do it was wrong. Hope can help.
I'm trying to setup Devise 3.1.0 with Rails 4.0.0.
I have configured my router like so:
devise_for :users,
:controllers => {
:registrations => 'users/registrations',
:sessions => 'users/sessions'
},
:path_names => {
:sign_in => 'login',
:sign_out => 'logout',
:sign_up => 'new'
}
new_user_session GET /users/login(.:format) users/sessions#new
user_session POST /users/login(.:format) users/sessions#create
destroy_user_session DELETE /users/logout(.:format) users/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) users/registrations#cancel
user_registration POST /users(.:format) users/registrations#create
new_user_registration GET /users/new(.:format) users/registrations#new
edit_user_registration GET /users/edit(.:format) users/registrations#edit
PATCH /users(.:format) users/registrations#update
PUT /users(.:format) users/registrations#update
DELETE /users(.:format) users/registrations#destroy
I've also turned on scoped views, and overridden the default views and registration controller:
# config/initializers/devise.rb
config.scoped_views = true
rails generate devise:views users
# app/controllers/users/registrations_controller.rb
#
# NOTE: I created this class, so creating new users could only be done by authenticated users.
#
class Users::RegistrationsController < Devise::RegistrationsController
before_filter :authenticate_user!
prepend_before_filter :authenticate_scope!
skip_before_filter :require_no_authentication
end
# app/controllers/users/sessions_controller.rb
# (currently empty)
class Users::SessionsController < Devise::SessionsController
end
The problem:
Why devise is ignoring the :path_names settings above in some situations?
For example, this method will not use the :sign_in setting above, and returns an incorrect path:
new_session_path(resource_name)
=> /users/sign_in
resource_name
=> user
Whereas this method returns the correct path:
new_user_session_path
=> /users/login
The problem is, Devise internally uses the former method, and keeps redirecting to the wrong path when the user is not signed in.
Have I mis-configured something, or is Devise not working correctly? Could this be a Rails 4 issue?
I'm not sure what the issue I was having was. (I'd still be interested to know, if anyone knows).
But I've found another way to express what I wanted with devise, and it seems to work OK:
devise_for :users,
:controllers => {
:registrations => 'users/registrations'
},
:path_names => {
:sign_up => 'new'
}, :skip => [:sessions]
as :user do
get '/users/login' => 'devise/sessions#new', :as => :new_user_session
post '/users/login' => 'devise/sessions#create', :as => :user_session
match '/users/logout' => 'devise/sessions#destroy', :as => :destroy_user_session,
:via => Devise.mappings[:user].sign_out_via
end
I think you trying to solve your question with the wrong feature, in this link show you how to write another routes for devise, in my app I've recreated the routes with this:
devise_scope :user do
get '/cadastrar' => 'devise/registrations#new'
get '/entrar' => 'devise/sessions#new'
get '/editar' => 'devise/registrations#edit'
delete '/sair' => 'devise/sessions#destroy'
end
I'm glad if work!
I am using devise and I want to customize its urls:
users/sign_in --> account/login
users/sign_up --> account/register
users/edit --> account/profile
...
Now my routes.rb looks like this:
devise_scope :user do
get '/account/login' => 'devise/sessions#new'
post 'account/login' => 'devise/sessions#create', as: :user_session
delete 'account/logout' => 'devise/sessions#destroy', as: :destroy_user_session
post 'account/password' => 'devise/passwords#update', as: :user_password
get 'account/password/forgot' => 'devise/passwords#new', as: :new_user_password
get 'account/password/edit' => 'devise/passwords#edit', as: :edit_user_password
put 'account/password' => 'devise/passwords#update'
get 'account/cancel' => 'devise/registrations#cancel', as: :cancel_user_registration
post 'account' => 'devise/registrations#create', as: :user_registration
get 'account/register' => 'devise/registrations#new', as: :new_user_registration
get 'account' => 'devise/registrations#edit', as: :edit_user_registration
put 'account' => 'devise/registrations#edit'
delete 'account' => 'devise/registrations#destroy'
end
devise_for :users
I manage to over-write profile, forgot, register bug not login:
So when I click on the link "Sign up" link in the generic Devise Login form I am redirected to /register in the browser, but when I click the "Sign in" link I am still redirected to /users/sign_in rather than login.
I tried match vs. post + get for the routes but without luck. I know that if I generate the forms myself I can decide how the links look like, but I would prefer to user the generic devise forms and also I am curious why the other routes work.
Running rake routes produces this (with the top five rows from my routes):
new_user_session GET /account/login(.:format) devise/sessions#new
user_session POST /account/login(.:format) devise/sessions#create
destroy_user_session DELETE /account/logout(.:format) devise/sessions#destroy
user_password POST /account/password(.:format) devise/passwords#update
new_user_password GET /account/password/forgot(.:format) devise/passwords#new
edit_user_password GET /account/password/edit(.:format) devise/passwords#edit
account_password PUT /account/password(.:format) devise/passwords#update
cancel_user_registration GET /account/cancel(.:format) devise/registrations#cancel
user_registration POST /account(.:format) devise/registrations#create
new_user_registration GET /account/register(.:format) devise/registrations#new
edit_user_registration GET /account(.:format) devise/registrations#edit
account PUT /account(.:format) devise/registrations#edit
DELETE /account(.:format) devise/registrations#destroy
new_user_session GET /users/sign_in(.:format) devise/sessions#new
POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
POST /users/password(.:format) devise/passwords#create
GET /users/password/new(.:format) devise/passwords#new
GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
GET /users/cancel(.:format) devise/registrations#cancel
POST /users(.:format) devise/registrations#create
GET /users/sign_up(.:format) devise/registrations#new
GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root / posts#show
Update: I am now mimicking all of devise's routes (See updated routes.rb). But I am still redirected to /users/sign_in
You can try this, This is working
see more help devise wiki
devise_for :users, :path => '', :path_names => {:sign_in => 'login', :sign_out => 'logout'}
This should work. Also remove the /account and add path account to your routes file like I've done below.
devise_scope :user, path: "account" do
get "login", :to => "devise/sessions#new", :as => "login"
get "signup" => "users/registrations#new", :as => "register"
get "edit" => "edit_user_registration", :as => "edit"
end