From 4837bb0a4e5a1ea00e732f48ee2acef90606a31e Mon Sep 17 00:00:00 2001 From: Scott Jacobsen Date: Tue, 3 Mar 2015 22:37:25 -0700 Subject: [PATCH] Allow objects to specify their devise scope. Introspecting the scope of an object can make it difficult to use wrapper patterns. See issue plataformatec/devise#3307 for an example. Allow objects to specify their scope explicitly by implementing `devise_scope`. --- lib/devise/mapping.rb | 1 + test/mapping_test.rb | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/lib/devise/mapping.rb b/lib/devise/mapping.rb index 5c40f762..af4a1412 100644 --- a/lib/devise/mapping.rb +++ b/lib/devise/mapping.rb @@ -31,6 +31,7 @@ module Devise # Receives an object and find a scope for it. If a scope cannot be found, # raises an error. If a symbol is given, it's considered to be the scope. def self.find_scope!(obj) + obj = obj.devise_scope if obj.respond_to?(:devise_scope) case obj when String, Symbol return obj.to_sym diff --git a/test/mapping_test.rb b/test/mapping_test.rb index d22bf0bc..2159997c 100644 --- a/test/mapping_test.rb +++ b/test/mapping_test.rb @@ -71,6 +71,12 @@ class MappingTest < ActiveSupport::TestCase assert_equal :user, Devise::Mapping.find_scope!(Class.new(User).new) end + test 'find scope uses devise_scope' do + user = User.new + def user.devise_scope; :special_scope; end + assert_equal :special_scope, Devise::Mapping.find_scope!(user) + end + test 'find scope raises an error if cannot be found' do assert_raise RuntimeError do Devise::Mapping.find_scope!(String)