Changing the sign_in url for Devise - ruby-on-rails

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

Devise custom routing links not working

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

Is it possible to have different paths on the same devise model with constraints?

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

Rails - error uninitialized constant MyNamespace::OmniauthCallbacksController

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.

Make devise paths unavailable

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 Can't find route in Functional Test

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

Resources