1
0
Fork 0
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:
José Valim 2010-07-04 11:53:12 +02:00
parent 18cccae82f
commit 7a1adbb61e
8 changed files with 86 additions and 32 deletions

View file

@ -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

View file

@ -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

View file

@ -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' " <<

View file

@ -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

View file

@ -0,0 +1,2 @@
class Publisher::RegistrationsController < ApplicationController
end

View file

@ -0,0 +1,2 @@
class Publisher::SessionsController < ApplicationController
end

View file

@ -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 => {

View file

@ -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