From d87ff26cbdc17b09fd2d636ee1600a8359658c12 Mon Sep 17 00:00:00 2001 From: "Carlos A. da Silva" Date: Fri, 16 Oct 2009 20:46:06 -0300 Subject: [PATCH] Allow setup of path_names in devise_for mapping for overwriting sign_in, sign_out, password and confirmation keywords. --- README.rdoc | 8 +++++-- lib/devise/mapping.rb | 6 ++++- lib/devise/routes.rb | 12 +++++----- test/mapping_test.rb | 16 +++++++++++++ test/rails_app/config/routes.rb | 3 +++ test/routes_test.rb | 40 +++++++++++++++++++++++---------- 6 files changed, 64 insertions(+), 21 deletions(-) diff --git a/README.rdoc b/README.rdoc index ffee8d0c..9cb8322c 100644 --- a/README.rdoc +++ b/README.rdoc @@ -93,13 +93,17 @@ This is going to look inside you User model and create the needed routes: You can run the routes rake task to verify what routes are being created by devise. There are also some options available for configuring your routes: +* :class_name => setup a different class to be looked up by devise, if it cannot be correctly find by the route name. + + map.devise_for :users, :class_name => 'Account' + * :as => Let's you setup the path name that will be used, as rails routes does. The following route configuration would setup your route as /accounts/session and so on: map.devise_for :users, :as => 'accounts' -* :class_name => setup a different class to be looked up by devise, if it cannot be correctly find by the route name. +* :path_names => configure different path names to overwrite defaults :sign_in, :sign_out, :password and :confirmation. - map.devise_for :users, :class_name => 'Account' + map.devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification' } And that is it! Devise is gonna create some helpers to use inside your controllers and views. To setup a controller that needs user authentication, just add this before_filter: diff --git a/lib/devise/mapping.rb b/lib/devise/mapping.rb index d268eac5..857fb330 100644 --- a/lib/devise/mapping.rb +++ b/lib/devise/mapping.rb @@ -6,12 +6,16 @@ module Devise }.freeze class Mapping - attr_reader :name, :as + attr_reader :name, :as, :path_names def initialize(name, options) @as = (options[:as] || name).to_sym @klass = (options[:class_name] || name.to_s.classify).to_s @name = (options[:singular] || name.to_s.singularize).to_sym + @path_names = options[:path_names] || {} + [:sign_in, :sign_out, :password, :confirmation].each do |path_name| + @path_names[path_name] ||= path_name.to_s + end end # Return modules for the mapping. diff --git a/lib/devise/routes.rb b/lib/devise/routes.rb index 74c80849..76c12440 100644 --- a/lib/devise/routes.rb +++ b/lib/devise/routes.rb @@ -22,7 +22,7 @@ module ActionController::Routing options = resources.extract_options! resources.map!(&:to_sym) - options.assert_valid_keys(:class_name, :as) + options.assert_valid_keys(:class_name, :as, :path_names) resources.each do |resource| mapping = Devise::Mapping.new(resource, options) @@ -30,19 +30,19 @@ module ActionController::Routing if mapping.authenticable? with_options(:controller => 'sessions', :path_prefix => mapping.as) do |session| - session.send(:"new_#{mapping.name}_session", 'sign_in', :action => 'new', :conditions => { :method => :get }) - session.send(:"#{mapping.name}_session", 'sign_in', :action => 'create', :conditions => { :method => :post }) - session.send(:"destroy_#{mapping.name}_session", 'sign_out', :action => 'destroy', :conditions => { :method => :get }) + session.send(:"new_#{mapping.name}_session", mapping.path_names[:sign_in], :action => 'new', :conditions => { :method => :get }) + session.send(:"#{mapping.name}_session", mapping.path_names[:sign_in], :action => 'create', :conditions => { :method => :post }) + session.send(:"destroy_#{mapping.name}_session", mapping.path_names[:sign_out], :action => 'destroy', :conditions => { :method => :get }) end end namespace mapping.name, :namespace => nil, :path_prefix => mapping.as do |m| if mapping.recoverable? - m.resource :password, :only => [:new, :create, :edit, :update] + m.resource :password, :only => [:new, :create, :edit, :update], :as => mapping.path_names[:password] end if mapping.confirmable? - m.resource :confirmation, :only => [:new, :create, :show] + m.resource :confirmation, :only => [:new, :create, :show], :as => mapping.path_names[:confirmation] end end end diff --git a/test/mapping_test.rb b/test/mapping_test.rb index 4b3d8d19..5639db03 100644 --- a/test/mapping_test.rb +++ b/test/mapping_test.rb @@ -35,6 +35,22 @@ class MapTest < ActiveSupport::TestCase assert_equal Devise.mappings[:admin], Devise.find_mapping_by_path("/admin_area/session") end + test 'return default path names' do + mapping = Devise.mappings[:user] + assert_equal 'sign_in', mapping.path_names[:sign_in] + assert_equal 'sign_out', mapping.path_names[:sign_out] + assert_equal 'password', mapping.path_names[:password] + assert_equal 'confirmation', mapping.path_names[:confirmation] + end + + test 'allow custom path names to be given' do + mapping = Devise.mappings[:account] + assert_equal 'login', mapping.path_names[:sign_in] + assert_equal 'logout', mapping.path_names[:sign_out] + assert_equal 'secret', mapping.path_names[:password] + assert_equal 'verification', mapping.path_names[:confirmation] + end + test 'magic predicates' do mapping = Devise.mappings[:user] assert mapping.authenticable? diff --git a/test/rails_app/config/routes.rb b/test/rails_app/config/routes.rb index f98d99d1..14137a43 100644 --- a/test/rails_app/config/routes.rb +++ b/test/rails_app/config/routes.rb @@ -1,6 +1,9 @@ ActionController::Routing::Routes.draw do |map| map.devise_for :users map.devise_for :admin, :as => 'admin_area' + map.devise_for :account, :path_names => { + :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification' + } map.resources :users, :only => :index map.resources :admins, :only => :index diff --git a/test/routes_test.rb b/test/routes_test.rb index 6bca5426..35d1019d 100644 --- a/test/routes_test.rb +++ b/test/routes_test.rb @@ -2,54 +2,70 @@ require 'test/test_helper' class MapRoutingTest < ActionController::TestCase - test 'map devise new user session' do + test 'map new user session' do assert_recognizes({:controller => 'sessions', :action => 'new'}, {:path => 'users/sign_in', :method => :get}) end - test 'map devise create user session' do + test 'map create user session' do assert_recognizes({:controller => 'sessions', :action => 'create'}, {:path => 'users/sign_in', :method => :post}) end - test 'map devise destroy user session' do + test 'map destroy user session' do assert_recognizes({:controller => 'sessions', :action => 'destroy'}, {:path => 'users/sign_out', :method => :get}) end - test 'map devise new user confirmation' do + test 'map new user confirmation' do assert_recognizes({:controller => 'confirmations', :action => 'new'}, 'users/confirmation/new') end - test 'map devise create user confirmation' do + test 'map create user confirmation' do assert_recognizes({:controller => 'confirmations', :action => 'create'}, {:path => 'users/confirmation', :method => :post}) end - test 'map devise show user confirmation' do + test 'map show user confirmation' do assert_recognizes({:controller => 'confirmations', :action => 'show'}, {:path => 'users/confirmation', :method => :get}) end - test 'map devise new user password' do + test 'map new user password' do assert_recognizes({:controller => 'passwords', :action => 'new'}, 'users/password/new') end - test 'map devise create user password' do + test 'map create user password' do assert_recognizes({:controller => 'passwords', :action => 'create'}, {:path => 'users/password', :method => :post}) end - test 'map devise edit user password' do + test 'map edit user password' do assert_recognizes({:controller => 'passwords', :action => 'edit'}, 'users/password/edit') end - test 'map devise update user password' do + test 'map update user password' do assert_recognizes({:controller => 'passwords', :action => 'update'}, {:path => 'users/password', :method => :put}) end - test 'map devise admin session with :as option' do + test 'map admin session with :as option' do assert_recognizes({:controller => 'sessions', :action => 'new'}, {:path => 'admin_area/sign_in', :method => :get}) end - test 'does not map devise admin confirmation' do + test 'does not map admin confirmation' do assert_raise ActionController::RoutingError do assert_recognizes({:controller => 'confirmations', :action => 'new'}, 'admin_area/confirmation/new') end end + test 'map account with custom path name for session sign in' do + assert_recognizes({:controller => 'sessions', :action => 'new'}, 'account/login') + end + + test 'map account with custom path name for session sign out' do + assert_recognizes({:controller => 'sessions', :action => 'destroy'}, 'account/logout') + end + + test 'map account with custom path name for password' do + assert_recognizes({:controller => 'passwords', :action => 'new'}, 'account/secret/new') + end + + test 'map account with custom path name for confirmation' do + assert_recognizes({:controller => 'confirmations', :action => 'new'}, 'account/verification/new') + end + end