How do you change the sign in path for Devise when using a before_filter :athenticate user?
I have the following in a Posts controller.
eg:
class PostsController < ApplicationController
before_filter :authenticate_user!
def index
#posts = Post.all
end
end
At the moment it automatically goes to '/users/sign_in'
I'd like to use '/login'
Sorted for now folks, using the devise_for method.
devise_for :users, :controllers => { :registrations => 'registrations' }, :path => 'accounts', :path_names => { :sign_in => 'login', :sign_up => 'new', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification' }
So now the sign_in path is 'accounts/login'
That solution doesn't modify the resource path for sign_in.
I did however sort it out via the devise_for method. eg:
devise_for :users,
:controllers => { :registrations => 'registrations' },
:path => 'accounts',
:path_names => { :sign_in => 'login',
:sign_up => 'new',
:sign_out => 'logout',
:password => 'secret',
:confirmation => 'verification' }
So now the sign_in path is 'accounts/login'
I think the info you are looking for is here: https://github.com/plataformatec/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes
Stolen from the docs:
devise_scope :user do
get "/login" => "devise/sessions#new"
end
In you case you would use :post instead of :user I believe.
Its late and I am fuzzy headed but I think that should do it.
Related
I am running Rails 3.2.12 and Devise 3.1 and I have in the routes.rb this:
devise_for :users do
get '/login' => 'devise/sessions#new', as: :login
get '/logout' => 'devise/sessions#destroy', as: :logout
end
However, when I hit
127.0.0.1:3000/login
I get
No route matches [GET] "/login"
What works is
127.0.0.1:3000/users/login
Is there anything else I have to do so that I can skip typing /users/ part?
Thank you!
devise_for :users, :path => '', :path_names => { :sign_in => 'login'}
Good info about customizing Devise paths on this StackOverflow post :)
Here's some live code which works for one of our live apps:
#User Management (Devise)
devise_for :users, :path => '', :controllers => {:sessions => 'sessions', :registrations => 'registrations'}, :path_names => { :sign_in => 'login', :password => 'forgot', :confirmation => 'confirm', :unlock => 'unblock', :registration => 'register', :sign_up => 'new', :sign_out => 'logout'}
as :user do
get 'register', :to => 'devise/registrations#new'
delete 'logout', :to => 'sessions#destroy'
end
devise_scope :user do
get "/login" => "devise/sessions#new"
end
See this for more details
I'm trying to have different paths for the same devise model/resource with constraints, but the first path is the one being applied in this case "visitor".
constraints(ValidSubdomainFrontend) do
devise_for :users, :path => "visitor", :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification', :unlock => 'unblock', :registration => 'register', :sign_up => 'cmon_let_me_in' }
end
constraints(ValidSubdomainAdmin) do
devise_for :users do
get 'users', :path => "admin", :to => 'site_backend#index', :as => :user_root # Rails 3
end
devise_for :users, :controllers => { :registrations => 'users' }, :path => "admin", :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification', :unlock => 'unblock', :registration => 'register', :sign_up => 'cmon_let_me_in' }
end
Is it possible to have different paths for the same resource with Devise on different constraints?
The constraints being used are:
class ValidSubdomainAdmin
def self.matches?(request)
request.subdomain.present? &&
request.env['PATH_INFO'].start_with?('/admin')
end
end
class ValidSubdomainFrontend
def self.matches?(request)
request.subdomain.present? &&
!request.env['PATH_INFO'].start_with?('/admin')
end
end
Is this possible with Devise at all or is this a Bug?
Found the solution for this issue!
More on the context, basically needed to have something like /visitor on the front-end where users can login (to the members area) and edit their profile and other members/clients operations. But I would also want /admin where admins/editors/authors can login to the (backend) admin dashboard/area. Both areas use the same Devise model/resource (so an admin can also visit the members area). As a side note, currently I'm using CanCan permissions to prevent members from accessing the admin area.
I just had to replace the admin area constraint for:
constraints(ValidSubdomainAdmin) do
devise_scope :user do
#root :to => "devise/registrations#new"
get "admin/" => "admin#index"
post 'admin/' => 'devise/registrations#new', :as => :new_admin_registration
match 'admin/', :to => 'admin#index'
get "admin/edit" => "devise/registrations#edit"
match 'admin/edit', :to => 'devise/registrations#edit'
get "admin/login" => "devise/sessions#new", :as => :new_admin_session
match 'admin/login', :to => 'devise/sessions#new'
get "admin/logout" => "devise/sessions#destroy", :as => 'destroy_admin_session'
match 'admin/logout', :to => 'devise/sessions#destroy'
post "admin/password" => "devise/passwords#create"
get "admin/password/new" => "devise/passwords#new", :as => 'new_admin_password'
get "admin/password/edit" => "devise/passwords#edit"
put "admin/password" => "devise/passwords#update"
end
end
I also updated the views /admin/users (being used by devise on the on the admin area) to use the new admin devise paths.
Many thanks to José Valim
I got an error like this:
uninitialized constant Mobile::OmniauthCallbacksController
It seems like a routes.rb issue. What exactly do I need to add to my namespace to make it work?
Here is the route scope:
scope :module => :mobile, :as => :mobile do
constraints(:subdomain => /m/) do
devise_for :users, :path => "", :path_names =>
{ :sign_in => "login", :sign_out => "logout",
:sign_up => "signup" },
:controllers => {:sessions => "mobile/sessions" , :passwords => "mobile/passwords" , :confirmations => "mobile/confirmations" , :registrations => "mobile/registrations"}
get "/home" => "home#index" , :as => "home"
end
end
Elsewhere in the routes.rb file there is a snippet like this:
devise_scope :user do
get "auth/:provider" => "users/omniauth_callbacks#passthru"
end
but I am not sure how to make it work within the namespace I am working in. Any ideas?
Thanks!
I believe the issue may be in your use of these values for your controllers:
{:sessions => "mobile/sessions" ,
:passwords => "mobile/passwords" ,
:confirmations => "mobile/confirmations" ,
:registrations => "mobile/registrations"
}
It looks like the code is getting into these controllers and trying to load OmniauthCallbacksController from inside the scope of Mobile.
How can i make devise paths unavailable. Now i have all forms for registration, authorization and password restore on one page.
Here are my routes
devise_for :users, :controllers => { :passwords => "passwords", :registrations => "registrations" }, :path => 'accounts', :path_names => { :sign_in => 'login', :sign_up => 'new', :sign_out => 'logout'}
so if i enter something like accounts/new in url, i will get to devise sign up page. Is it possible to make all devise pages unavailable? I should get RoutingError or MissingTemplate for example if i enter either of the devise routes.
Just skip the parts you don't want:
devise_for :users,
:controllers => {
:passwords => "passwords",
:registrations => "registrations" },
:path => 'accounts',
:path_names => {
:sign_in => 'login',
:sign_up => 'new',
:sign_out => 'logout'},
:skip => [:passwords, :registrations, :sessions]
Rails version 3.0.4 and Ruby 1.9.2
I'm using the devise gem, and have my application set up so that a user must sign in to perform any action. While writing my functional tests, I found that all of the test threw the same error.
`method_missing': undefined method `new_user_session_path'
This is strange as, if I rake routes I can see
new_user_session GET /devise/login(.:format) {:action=>"new", :controller=>"devise/sessions"}
I can also confirm that when I run the application, all of the link_tos work, when using that path.
Is there something special I have to do for a certain controller's test to see other routes?
routes.rb
Nge::Application.routes.draw do
resources :companies
resources :users
devise_for :users, :path => "devise", :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification', :unlock => 'unblock', :registration => 'register', :sign_up => 'cmon_let_me_in' }
...
end
test/functional/companies_controller_test.rb
require 'test_helper'
class CompaniesControllerTest < ActionController::TestCase
context "When a user is NOT signed in" do
[:index, :new].each do |action|
context "and GET ##{action.to_s}" do
setup {get action}
should set_the_flash.to(/must sign-up/)
should redirect_to(new_user_session_path)
end
end
...
end
end
You need to add
#request.env["devise.mapping"] = Devise.mappings[:user]
somewhere in your test, probably in the setup method.
See discussion here.
Can you try re-ordering the routes so that the devise routes are first?
So the routes.rb file would look something like this -
Nge::Application.routes.draw do
resources :companies
devise_for :users, :path => "devise", :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification', :unlock => 'unblock', :registration => 'register', :sign_up => 'cmon_let_me_in' }
resources :users
...
end