mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
Improve integration of devise with new router scope.
This commit is contained in:
parent
18cccae82f
commit
7a1adbb61e
8 changed files with 86 additions and 32 deletions
|
@ -2,9 +2,6 @@
|
|||
* Rememberable module allows user to be remembered across browsers and is enabled by default (by github.com/trevorturk)
|
||||
* devise_for can now be used together with scope method in routes but with a few limitations (check the documentation)
|
||||
|
||||
* deprecation
|
||||
* :path_prefix option in devise_for is no longer supported
|
||||
|
||||
* bug fix
|
||||
* Fix a bug in Devise::TestHelpers where current_user was returning a Response object for non active accounts
|
||||
* Devise should respect script_name and path_info contracts
|
||||
|
|
|
@ -56,23 +56,13 @@ module Devise
|
|||
end
|
||||
|
||||
def initialize(name, options) #:nodoc:
|
||||
if as = options.delete(:as)
|
||||
ActiveSupport::Deprecation.warn ":as is deprecated, please use :path instead."
|
||||
options[:path] ||= as
|
||||
end
|
||||
|
||||
if scope = options.delete(:scope)
|
||||
ActiveSupport::Deprecation.warn ":scope is deprecated, please use :singular instead."
|
||||
options[:singular] ||= scope
|
||||
end
|
||||
|
||||
@plural = name.to_sym
|
||||
@path = (options.delete(:path) || name).to_sym
|
||||
@singular = (options.delete(:singular) || name.to_s.singularize).to_sym
|
||||
@plural = (options[:as] ? "#{options.delete(:as)}_#{name}" : name).to_sym
|
||||
@singular = (options.delete(:singular) || @plural.to_s.singularize).to_sym
|
||||
|
||||
@class_name = (options.delete(:class_name) || name.to_s.classify).to_s
|
||||
@ref = ActiveSupport::Dependencies.ref(@class_name)
|
||||
|
||||
@path = (options.delete(:path) || name).to_sym
|
||||
@path_prefix = "/#{options.delete(:path_prefix)}/".squeeze("/")
|
||||
|
||||
if @path_prefix =~ /\(.*\)/ && Devise.ignore_optional_segments != true
|
||||
|
@ -81,7 +71,8 @@ module Devise
|
|||
"what you are doing, you can set config.ignore_optional_segments = true in your devise initializer."
|
||||
end
|
||||
|
||||
@controllers = Hash.new { |h,k| h[k] = "devise/#{k}" }
|
||||
mod = options.delete(:module) || "devise"
|
||||
@controllers = Hash.new { |h,k| h[k] = "#{mod}/#{k}" }
|
||||
@controllers.merge!(options.delete(:controllers) || {})
|
||||
|
||||
@path_names = Hash.new { |h,k| h[k] = k.to_s }
|
||||
|
@ -117,11 +108,16 @@ module Devise
|
|||
end
|
||||
end
|
||||
|
||||
# Return in which position in the path prefix devise should find the as mapping.
|
||||
# Returns in which position in the path prefix devise should find the as mapping.
|
||||
def segment_position
|
||||
self.path_prefix.count("/")
|
||||
end
|
||||
|
||||
# Returns fullpath for route generation.
|
||||
def fullpath
|
||||
@path_prefix + @path.to_s
|
||||
end
|
||||
|
||||
def authenticatable?
|
||||
@authenticatable ||= self.modules.any? { |m| m.to_s =~ /authenticatable/ }
|
||||
end
|
||||
|
|
|
@ -98,13 +98,6 @@ module ActionDispatch::Routing
|
|||
# end
|
||||
# end
|
||||
#
|
||||
# Second, since Devise expects routes in the format "user_session_path" to be defined, you cannot
|
||||
# scope to a given route name as below:
|
||||
#
|
||||
# scope "/special_scope", :as => :special_scope do # THIS WILL FAIL
|
||||
# devise_for :users
|
||||
# end
|
||||
#
|
||||
# Finally, Devise does not (and cannot) support optional segments, either static or dynamic. That
|
||||
# said, the following does not work:
|
||||
#
|
||||
|
@ -115,12 +108,21 @@ module ActionDispatch::Routing
|
|||
def devise_for(*resources)
|
||||
options = resources.extract_options!
|
||||
|
||||
if options.key?(:path_prefix)
|
||||
ActiveSupport::Deprecation.warn "Giving :path_prefix to devise_for is deprecated and has no effect. " <<
|
||||
"Please use scope from the new router DSL instead."
|
||||
if as = options.delete(:as)
|
||||
ActiveSupport::Deprecation.warn ":as is deprecated, please use :path instead."
|
||||
options[:path] ||= as
|
||||
end
|
||||
|
||||
options[:path_prefix] = @scope[:path]
|
||||
if scope = options.delete(:scope)
|
||||
ActiveSupport::Deprecation.warn ":scope is deprecated, please use :singular instead."
|
||||
options[:singular] ||= scope
|
||||
end
|
||||
|
||||
options[:as] ||= @scope[:as] if @scope[:as].present?
|
||||
options[:module] ||= @scope[:module] if @scope[:module].present?
|
||||
options[:path_prefix] ||= @scope[:path] if @scope[:path].present?
|
||||
options[:path_names] = (@scope[:path_names] || {}).merge(options[:path_names] || {})
|
||||
|
||||
resources.map!(&:to_sym)
|
||||
|
||||
resources.each do |resource|
|
||||
|
@ -141,7 +143,7 @@ module ActionDispatch::Routing
|
|||
routes = mapping.routes
|
||||
routes -= Array(options.delete(:skip)).map { |s| s.to_s.singularize.to_sym }
|
||||
|
||||
scope mapping.path.to_s, :as => mapping.name do
|
||||
with_devise_scope mapping.fullpath, mapping.name do
|
||||
routes.each { |mod| send(:"devise_#{mod}", mapping, mapping.controllers) }
|
||||
end
|
||||
end
|
||||
|
@ -193,6 +195,14 @@ module ActionDispatch::Routing
|
|||
:path_names => { :new => mapping.path_names[:sign_up] }, :controller => controllers[:registrations]
|
||||
end
|
||||
|
||||
def with_devise_scope(new_path, new_as)
|
||||
old_as, old_path, old_module = @scope[:as], @scope[:path], @scope[:module]
|
||||
@scope[:as], @scope[:path], @scope[:module] = new_as, new_path, nil
|
||||
yield
|
||||
ensure
|
||||
@scope[:as], @scope[:path], @scope[:module] = old_as, old_path, old_module
|
||||
end
|
||||
|
||||
def raise_no_devise_method_error!(klass)
|
||||
raise "#{klass} does not respond to 'devise' method. This usually means you haven't " <<
|
||||
"loaded your ORM file or it's being loaded too late. To fix it, be sure to require 'devise/orm/YOUR_ORM' " <<
|
||||
|
|
|
@ -44,4 +44,15 @@ class RoutesTest < ActionController::TestCase
|
|||
assert_path_and_url :confirmation
|
||||
assert_path_and_url :confirmation, :new
|
||||
end
|
||||
|
||||
test 'should alias unlock to mapped user unlock' do
|
||||
assert_path_and_url :unlock
|
||||
assert_path_and_url :unlock, :new
|
||||
end
|
||||
|
||||
test 'should alias registration to mapped user registration' do
|
||||
assert_path_and_url :registration
|
||||
assert_path_and_url :registration, :new
|
||||
assert_path_and_url :registration, :edit
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
class Publisher::RegistrationsController < ApplicationController
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
class Publisher::SessionsController < ApplicationController
|
||||
end
|
|
@ -9,6 +9,10 @@ Rails.application.routes.draw do
|
|||
devise_for :users
|
||||
devise_for :admin, :path => "admin_area", :controllers => { :sessions => "sessions" }, :skip => :passwords
|
||||
|
||||
namespace :publisher, :path_names => { :sign_in => "i_don_care", :sign_out => "get_out" } do
|
||||
devise_for :accounts, :class_name => "User", :path_names => { :sign_in => "get_in" }
|
||||
end
|
||||
|
||||
scope ":locale" do
|
||||
devise_for :accounts, :singular => "manager", :class_name => "User",
|
||||
:path_names => {
|
||||
|
|
|
@ -1,25 +1,29 @@
|
|||
require 'test_helper'
|
||||
|
||||
class MapRoutingTest < ActionController::TestCase
|
||||
|
||||
class DefaultRoutingTest < ActionController::TestCase
|
||||
test 'map new user session' do
|
||||
assert_recognizes({:controller => 'devise/sessions', :action => 'new'}, {:path => 'users/sign_in', :method => :get})
|
||||
assert_named_route "/users/sign_in", :new_user_session_path
|
||||
end
|
||||
|
||||
test 'map create user session' do
|
||||
assert_recognizes({:controller => 'devise/sessions', :action => 'create'}, {:path => 'users/sign_in', :method => :post})
|
||||
assert_named_route "/users/sign_in", :user_session_path
|
||||
end
|
||||
|
||||
test 'map destroy user session' do
|
||||
assert_recognizes({:controller => 'devise/sessions', :action => 'destroy'}, {:path => 'users/sign_out', :method => :get})
|
||||
assert_named_route "/users/sign_out", :destroy_user_session_path
|
||||
end
|
||||
|
||||
test 'map new user confirmation' do
|
||||
assert_recognizes({:controller => 'devise/confirmations', :action => 'new'}, 'users/confirmation/new')
|
||||
assert_named_route "/users/confirmation/new", :new_user_confirmation_path
|
||||
end
|
||||
|
||||
test 'map create user confirmation' do
|
||||
assert_recognizes({:controller => 'devise/confirmations', :action => 'create'}, {:path => 'users/confirmation', :method => :post})
|
||||
assert_named_route "/users/confirmation", :user_confirmation_path
|
||||
end
|
||||
|
||||
test 'map show user confirmation' do
|
||||
|
@ -28,14 +32,17 @@ class MapRoutingTest < ActionController::TestCase
|
|||
|
||||
test 'map new user password' do
|
||||
assert_recognizes({:controller => 'devise/passwords', :action => 'new'}, 'users/password/new')
|
||||
assert_named_route "/users/password/new", :new_user_password_path
|
||||
end
|
||||
|
||||
test 'map create user password' do
|
||||
assert_recognizes({:controller => 'devise/passwords', :action => 'create'}, {:path => 'users/password', :method => :post})
|
||||
assert_named_route "/users/password", :user_password_path
|
||||
end
|
||||
|
||||
test 'map edit user password' do
|
||||
assert_recognizes({:controller => 'devise/passwords', :action => 'edit'}, 'users/password/edit')
|
||||
assert_named_route "/users/password/edit", :edit_user_password_path
|
||||
end
|
||||
|
||||
test 'map update user password' do
|
||||
|
@ -44,10 +51,12 @@ class MapRoutingTest < ActionController::TestCase
|
|||
|
||||
test 'map new user unlock' do
|
||||
assert_recognizes({:controller => 'devise/unlocks', :action => 'new'}, 'users/unlock/new')
|
||||
assert_named_route "/users/unlock/new", :new_user_unlock_path
|
||||
end
|
||||
|
||||
test 'map create user unlock' do
|
||||
assert_recognizes({:controller => 'devise/unlocks', :action => 'create'}, {:path => 'users/unlock', :method => :post})
|
||||
assert_named_route "/users/unlock", :user_unlock_path
|
||||
end
|
||||
|
||||
test 'map show user unlock' do
|
||||
|
@ -56,14 +65,17 @@ class MapRoutingTest < ActionController::TestCase
|
|||
|
||||
test 'map new user registration' do
|
||||
assert_recognizes({:controller => 'devise/registrations', :action => 'new'}, 'users/sign_up')
|
||||
assert_named_route "/users/sign_up", :new_user_registration_path
|
||||
end
|
||||
|
||||
test 'map create user registration' do
|
||||
assert_recognizes({:controller => 'devise/registrations', :action => 'create'}, {:path => 'users', :method => :post})
|
||||
assert_named_route "/users", :user_registration_path
|
||||
end
|
||||
|
||||
test 'map edit user registration' do
|
||||
assert_recognizes({:controller => 'devise/registrations', :action => 'edit'}, {:path => 'users/edit', :method => :get})
|
||||
assert_named_route "/users/edit", :edit_user_registration_path
|
||||
end
|
||||
|
||||
test 'map update user registration' do
|
||||
|
@ -74,6 +86,14 @@ class MapRoutingTest < ActionController::TestCase
|
|||
assert_recognizes({:controller => 'devise/registrations', :action => 'destroy'}, {:path => 'users', :method => :delete})
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def assert_named_route(result, name)
|
||||
assert_equal result, @routes.url_helpers.send(name)
|
||||
end
|
||||
end
|
||||
|
||||
class CustomizedRoutingTest < ActionController::TestCase
|
||||
test 'map admin with :path option' do
|
||||
assert_recognizes({:controller => 'devise/registrations', :action => 'new'}, {:path => 'admin_area/sign_up', :method => :get})
|
||||
end
|
||||
|
@ -112,3 +132,15 @@ class MapRoutingTest < ActionController::TestCase
|
|||
assert_recognizes({:controller => 'devise/registrations', :action => 'new', :locale => 'en'}, '/en/accounts/management/register')
|
||||
end
|
||||
end
|
||||
|
||||
class ScopedRoutingTest < ActionController::TestCase
|
||||
test 'map publisher account' do
|
||||
assert_recognizes({:controller => 'publisher/registrations', :action => 'new'}, {:path => '/publisher/accounts/sign_up', :method => :get})
|
||||
assert_equal '/publisher/accounts/sign_up', @routes.url_helpers.new_publisher_account_registration_path
|
||||
end
|
||||
|
||||
test 'map publisher account merges path names' do
|
||||
assert_recognizes({:controller => 'publisher/sessions', :action => 'new'}, {:path => '/publisher/accounts/get_in', :method => :get})
|
||||
assert_equal '/publisher/accounts/get_in', @routes.url_helpers.new_publisher_account_session_path
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue