I have this routes.rb:
devise_for :users, :path => '', path_names:
{ sign_in: "login", sign_out: "logout", sign_up: "registration"}
I changed sign_in and sign_up routes and if you go to sign_up you will get 404 error, instead /registration will work. What I want is to change and add other routes like forgotten password in the same way.
If I type in the console rake routes, I see this for forgotten password:
new_user_password GET /password/new(.:format) devise/passwords#new
How can add the additional routes in a way that my custom defined route will work, but not the default?
Be sure to checkout the ActionDispatch::Routing::Mapper#devise_for documentation here.
You can just simply do something like this-
devise_for :users, path: 'auth', path_names: { sign_in: 'login',
sign_out: 'logout',
password: 'secret',
confirmation: 'verification',
unlock: 'unblock',
registration: 'register',
sign_up: 'cmon_let_me_in' }
Here is an example for the sessions, registrations, and passwords controller actions/routes:
devise_for :users, skip: [:sessions, :registrations, :passwords]
devise_scope :user do
# sessions
get 'login', to: 'devise/sessions#new', as: :new_user_session
post 'login', to: 'devise/sessions#create', as: :user_session
delete 'logout', to: 'devise/sessions#destroy', as: :destroy_user_session
# registrations
put '/account', to: 'devise/registrations#update'
delete '/account', to: 'devise/registrations#destroy'
post '/account', to: 'devise/registrations#create'
get '/register', to: 'devise/registrations#new', as: :new_user_registration
get '/account', to: 'devise/registrations#edit', as: :edit_user_registration
patch '/account', to: 'devise/registrations#update', as: :user_registration
get '/account/cancel', to: 'devise/registrations#cancel', as: :cancel_user_registration# passwords
# passwords
get 'new-pass', to: 'devise/passwords#new', as: :new_user_password
get 'edit-pass', to: 'devise/passwords#edit', as: :edit_user_password
patch 'edit-pass', to: 'devise/passwords#update', as: :user_password
post 'new-pass', to: 'devise/passwords#create', as: :user_password
end
As seen in the 4th code sample block in this wiki
You need to skip passwords and rebuild its routes as you want,
devise_for :users, skip: [:passwords]
devise_scope :user do
match '/forgotten-password' => 'devise/passwords#create', as: :user_password, via: [:post]
match '/forgotten-password' => 'devise/passwords#update', via: [:put, :patch]
get 'forgotten-password', to: 'devise/passwords#new', as: :new_user_password
end
Your custom routes will work. And it skip all routes in that modules.
NOTE : You need to overwrite all remaining routes of that module as you want.
Related
I'm trying to use custom paths for the registration and session with Devise.
My problem is that the routes can't have the same 'as'.
My code is this:
#Devise
devise_for :users, skip: [:sessions,:registration]
as :user do
get 'signup', to: 'users/registrations#new', as: :new_user_registration
post 'signup', to: 'users/registrations#create', as: :user_registration
get 'edit', to: 'users/registrations#edit', as: :edit_user_registration
put 'edit', to: 'users/registrations#update' , as: :user_registration
get 'signin', to: 'users/sessions#new', as: :new_user_session
post 'signin', to: 'users/sessions#create', as: :user_session
delete 'signout', to: 'users/sessions#destroy', as: :destroy_user_session
end
How you can see the problem is the put request for 'edit' has to have the same as: as the post
How can I fix this? with a match?
devise_for :users, skip: [:sessions, :registrations, :passwords]
devise_scope :user do
# sessions
get 'login', to: 'devise/sessions#new', as: :new_user_session
post 'login', to: 'devise/sessions#create', as: :user_session
delete 'logout', to: 'devise/sessions#destroy', as: :destroy_user_session
# registrations
put '/account', to: 'devise/registrations#update'
delete '/account', to: 'devise/registrations#destroy'
post '/account', to: 'devise/registrations#create'
get '/register', to: 'devise/registrations#new', as: :new_user_registration
get '/account', to: 'devise/registrations#edit', as: :edit_user_registration
patch '/account', to: 'devise/registrations#update', as: :user_registration
get '/account/cancel', to: 'devise/registrations#cancel', as: :cancel_user_registration# passwords
# passwords
get 'new-pass', to: 'devise/passwords#new', as: :new_user_password
get 'edit-pass', to: 'devise/passwords#edit', as: :edit_user_password
patch 'edit-pass', to: 'devise/passwords#update', as: :user_password
post 'new-pass', to: 'devise/passwords#create', as: :user_password
end
check the code below for customizing devise routes
According to the naming conventions, your patch/put helper should be named user_registration as you have done already, and you post helper should be named user_registrations, that's to say in the plural form.
Please, check out the http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default to be more confident in rails routing DSL and routing conventions.
i want to ovverride my devise routes and the sessions controller from this gem at the same time. How do i do this ?
I thought about :
devise_for :admins, :skip => [:sessions],
controllers: { sessions: "admins/sessions" }
devise_scope :admin do
get 'login' => 'devise/sessions#new', :as => :new_admin_session
post 'login' => 'devise/sessions#create', :as => :admin_session
delete 'logout' => 'devise/sessions#destroy', :as => :destroy_admin_session
end
but my paths are chaging but the controller - not. How can I implement this right ?
When you specify controllers: { sessions: "admins/sessions" }, that implies that you have a file called sessions_controller.rb in this path: app/controllers/admins/sessions_controller.rb, and that it starts with:
module Admins
class SessionsController < Devise::SessionsController
If this is the controller you want your app to use, then in the devise_scope block, you must tell it to use admins/sessions, not devise/sessions, like this:
devise_scope :admin do
get 'login' => 'admins/sessions#new', :as => :new_admin_session
post 'login' => 'admins/sessions#create', :as => :admin_session
delete 'logout' => 'admins/sessions#destroy', :as => :destroy_admin_session
end
What about something like:
devise_for :admin, exclude: [:sessions] do
get '/login', to: 'sessions#new', as: :new_admin_session
post '/login', to: 'sessions#create', as: :admin_session
delete '/logout', to: 'sessions#destroy', as: :destroy_admin_session
end
I am using 'devise', '~> 3.4.1' and rails 4 in my app. When I try to create custom routes am getting wiered error. What else I need to add in my route.rb
Error:
ArgumentError: ' devise/sessions' is not a supported controller name.
This can lead to potential routing problems.
See
routes.rb
Rails.application.routes.draw do
devise_for :users
devise_scope :user do
get 'register', to: 'devise/registrations#new', as: :register
get 'login', to: ' devise/sessions#new', as: :login
end
The problem occured at login route.
There is a typo in your code, a space before 'devise/sessions#new'.
This,
get 'login', to: ' devise/sessions#new', as: :login
should be
get 'login', to: 'devise/sessions#new', as: :login
Try out this code:
devise_scope :user do
get '/login' => 'devise/sessions#new'
get '/register' => 'devise/registrations#new'
end
You need to do it this
devise_for :users, path_names: {
sign_in: 'login', sign_out: 'logout',
password: 'secret', confirmation: 'verification',
registration: 'register', edit: 'edit/profile'
}
Source:
http://www.rubydoc.info/github/plataformatec/devise/ActionDispatch/Routing/Mapper:devise_for
devise_for :user, :path => ' ', :path_names => { :sign_in => "login" :sign_up => "register" }
Currently, when a user logs in or signs up, they are redirected to /users/1, for example, as their show page.
I can't figure out what routes to use to redirect them to just the site root (example.com, for example, instead of example.com/users/1). The logged in site root would be the show page, the logged out site root would be the normal site home page.
I'm using devise, if it matters.
Current routes:
devise_for :users, :path => '', :path_names => { :sign_in => 'login', :sign_out => 'logout',
:password => 'password', :confirmation => 'verification',
:unlock => 'unblock', :registration => 'signup',
:sign_up => 'new' }
devise_scope :user do
get 'login', to: 'devise/sessions#new'
get 'users/login', to: 'devise/sessions#new'
get 'logout', to: 'devise/sessions#destroy'
get 'signup', to: 'devise/registrations#new'
get 'password', to: 'devise/passwords#new'
match 'users/secret', to: "devise/passwords#create", via: :post
match 'sessions/user', to: 'devise/sessions#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
end
resources :users
resources :sessions
root 'site#index'
Updated Routes:
devise_for :users, :path => '', :path_names => { :sign_in => 'login', :sign_out => 'logout',
:password => 'password', :confirmation => 'verification',
:unlock => 'unblock', :registration => 'signup',
:sign_up => 'new' }
get 'login' => 'users/login'
devise_scope :user do
get 'login', to: 'devise/sessions#new'
get 'users/login', to: 'devise/sessions#new'
get 'logout', to: 'devise/sessions#destroy'
get 'signup', to: 'devise/registrations#new'
get 'password', to: 'devise/passwords#new'
match 'users/secret', to: "devise/passwords#create", via: :post
match 'sessions/user', to: 'devise/sessions#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
end
get '', to: 'users#show', as: 'user'
get 'edit', to: 'users#edit', as: 'user/edit'
#resources :users
resources :sessions
# Authenticated Users:
authenticated :user do
root to: "users#show", as: :authenticated_root
end
# Non-Authenticated Users
root to: 'site#index'
You can use authenticated and unauthenticated resources.
Like this:
authenticated :user do
root to: "users#show", as: :authenticated_root, via: :get
end
unauthenticated do
root 'site#index'
end
Then in your users controller you'll need to make sure to check for the devise helper current_user instead of the id because you aren't passing one.
like
if params[:id]
#user = User.find params[:id]
else
#user = current_user
end
If you don't want users to be able to access this route, its easier to manage in the controller. Just modify the if statement, something like
if params[:id]
if current_user
#user = current_user
else
flash[:notice] = "This page is not available"
redirect_to root_path
end
else
#user = current_user
end
Updated routes:
devise_for :users, :path => '', :path_names => { :sign_in => 'login', :sign_out => 'logout',
:password => 'password', :confirmation => 'verification',
:unlock => 'unblock', :registration => 'signup',
:sign_up => 'new' }
get 'login' => 'users/login'
devise_scope :user do
get 'login', to: 'devise/sessions#new'
get 'users/login', to: 'devise/sessions#new'
get 'logout', to: 'devise/sessions#destroy'
get 'signup', to: 'devise/registrations#new'
get 'password', to: 'devise/passwords#new'
match 'users/secret', to: "devise/passwords#create", via: :post
match 'sessions/user', to: 'devise/sessions#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
end
#resources :users
resources :sessions
# Authenticated Users:
authenticated :user do
root to: "users#show", as: :authenticated_root
end
# Non-Authenticated Users
root to: 'site#index'
get '', to: 'users#show', as: 'user'
get 'edit', to: 'users#edit' as: 'user'
In your routes.rb (change the destination to: to the pages you wish)
YourApp::Application.routes.draw do
...
# Authenticated Users:
authenticated :user do
root to: 'user#show', as: :authenticated_root
end
# Non-Authenticated Users
root to: 'site#index'
end
Rails 4 Fix: https://github.com/plataformatec/devise/issues/2393#issuecomment-17298414
In UserController.rb: Make sure in your show method, that you use current_user instead of params[:id]. You do this because typically whenever you call your show action you send it an id, however in this case, you're not going to be doing so.
class UsersController < ApplicationController
def show
if params[:id].present?
#user = User.find(params[:id])
else
#user = current_user
end
end
end
I am using devise plugin in my new Rails App. My issue is devise plugin has default roots for login and signup
/users/sign_in
/users/sign_up
I need to change this to
/login
/signup
For this I used the following routing
devise_for :users do
get "login", :to => "devise/sessions#new"
get "signup", :to => "devise/registrations#new"
end
With this I need to specify 'login_path' and 'signup_path' everywhere in my views where new_user_session_path and new_user_registration_path comes
What I want is a configuration in routes which maps '/login' and '/signup' to new_user_session_path and new_user_registration_path.
I have seen a post which route /users/sign_in and /users/sign_up to /sign_in and /sign_up using the below shown routing.
devise_for :user, :as => ''
I need some routing technique like this which routes /users/sign_in and /users/sign_up to /login and /signup.
Could anyone please help me with this.
UPDATE: I have changed my routes.rb file to
devise_for :users,
:controllers => { :sessions => 'devise/sessions'},
:skip => [:sessions] do
get '/login' => "devise/sessions#new", :as => :new_user_session
post '/login' => 'devise/sessions#create', :as => :user_session
get '/signout' => 'devise/sessions#destroy', :as => :destroy_user_session
get '/signup' => 'devise/registrations#new', :as => :new_user_registration
end
But still when I use link_to 'new_user_registration' in my views its not showing as '/signup' in the browser
Here are a little bit more options than you asked but it's clear:
devise_for :users,
:controllers => { :registrations => "users/registrations",
:confirmations => "users/confirmations",
:sessions => 'devise/sessions'},
:skip => [:sessions] do
get '/signin' => "devise/sessions#new", :as => :new_user_session
post '/signin' => 'devise/sessions#create', :as => :user_session
get '/signout' => 'devise/sessions#destroy', :as => :destroy_user_session
get "/signup" => "users/registrations#new", :as => :new_user_registration
end
Even more, with :registrations => "users/registrations" we can additionally customize redirects:
class Users::RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
welcome_path # it's not a home path
end
def after_update_path_for(resource)
edit_user_registration_path
end
end
Devise has a good wiki.
I was able to fix my issue by using the following code in my routes
devise_for :users,
:controllers => { :sessions => 'devise/sessions'},
:skip => [:sessions] do
get '/login' => "devise/sessions#new", :as => :new_user_session
post '/login' => 'devise/sessions#create', :as => :user_session
get '/signout' => 'devise/sessions#destroy', :as => :destroy_user_session
get "/signup" => "devise/registrations#new", :as => :new_user_registration
end
But still in my views if I use
link_to "Register", new_user_registration_path
In my browser its showing as
/user/sign_up and not as /signup
But if I directly type /signup I will get the registraion page. Is there any mapping I need to do here.
i hope i'm not too late ;)
here is how it works (just paste it in your routes.rb and you good to go):
devise_for :users, :controllers => {:sessions => 'devise/sessions'}, :skip => [:sessions] do
get 'login' => 'devise/sessions#new', :as => :new_user_session
post 'login' => 'devise/sessions#create', :as => :user_session
get 'logout' => 'devise/sessions#destroy', :as => :destroy_user_session
get 'register' => 'devise/registrations#new', :as => :new_user_registration
end
edit config/routes.rb
devise_for :users, path: ''
devise_for :users, path: '', path_names: { sign_in: 'login', sign_out: 'logout', password: 'secret', confirmation: 'verification', unlock: 'unblock', registration: 'register', sign_up: 'cmon_let_me_in' }
new_user_session GET /login(.:format) devise/sessions#new
user_session POST /login(.:format) devise/sessions#create
destroy_user_session DELETE /logout(.:format) devise/sessions#destroy
user_password POST /secret(.:format) devise/passwords#create
new_user_password GET /secret/new(.:format) devise/passwords#new
edit_user_password GET /secret/edit(.:format) devise/passwords#edit
PATCH /secret(.:format) devise/passwords#update
PUT /secret(.:format) devise/passwords#update
cancel_user_registration GET /register/cancel(.:format) devise/registrations#cancel
user_registration POST /register(.:format) devise/registrations#create
new_user_registration GET /register/cmon_let_me_in(.:format) devise/registrations#new
edit_user_registration GET /register/edit(.:format) devise/registrations#edit
PATCH /register(.:format) devise/registrations#update
PUT /register(.:format) devise/registrations#update
DELETE /register(.:format) devise/registrations#destroy
As this may still be the n°1 result people get when looking for that question, it might be useful to note that there is now a simple way to do that:
devise_for :users, path: '', path_names: { sign_in: 'login', sign_up: 'signup'}
Reference: https://github.com/heartcombo/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes
If I am reading and understanding your question correctly, you are after 'match'.
devise_for :users
match "/login" => "devise/sessions#new"
match "/signup" => "devise/registrations#new"
Be sure to have them in the correct order as they are matched based on line numbers in the file.
More can be found at: http://guides.rubyonrails.org/routing.html