Allow scoped views to be customized per controller/mailer class.

This commit is contained in:
José Valim 2010-02-08 17:33:22 +01:00
parent 54cd2cc0e8
commit 9798ad7455
6 changed files with 42 additions and 4 deletions

View File

@ -1,5 +1,7 @@
* enhancements
* Added Registerable
* Added Http Basic Authentication support
* Allow scoped_views to be customized per controller/mailer class
== 0.9.2

View File

@ -1,4 +1,5 @@
class DeviseMailer < ::ActionMailer::Base
extend Devise::Controllers::InternalHelpers::ScopedViews
# Deliver confirmation instructions when the user is created or its email is
# updated, and also when confirmation is manually requested
@ -31,7 +32,7 @@ class DeviseMailer < ::ActionMailer::Base
end
def render_with_scope(key, mapping, assigns)
if Devise.scoped_views
if self.class.scoped_views
begin
render :file => "devise_mailer/#{mapping.as}/#{key}", :body => assigns
rescue ActionView::MissingTemplate

View File

@ -140,7 +140,7 @@ module Devise
# Tell when to use the default scope, if one cannot be found from routes.
mattr_accessor :use_default_scope
@@use_default_scope
@@use_default_scope = false
# The default scope which is used by warden.
mattr_accessor :default_scope
@ -148,7 +148,7 @@ module Devise
# Address which sends Devise e-mails.
mattr_accessor :mailer_sender
@@mailer_sender
@@mailer_sender = nil
# Authentication token params key name of choice. E.g. /users/sign_in?some_key=...
mattr_accessor :token_authentication_key

View File

@ -7,6 +7,7 @@ module Devise
def self.included(base)
base.class_eval do
extend ScopedViews
unloadable
helper_method :resource, :scope_name, :resource_name, :resource_class, :devise_mapping, :devise_controller?
@ -17,6 +18,16 @@ module Devise
end
end
module ScopedViews
def scoped_views
defined?(@scoped_views) ? @scoped_views : Devise.scoped_views
end
def scoped_views=(value)
@scoped_views = value
end
end
# Gets the actual resource stored in the instance variable
def resource
instance_variable_get(:"@#{resource_name}")
@ -104,7 +115,8 @@ module Devise
# Accepts just :controller as option.
def render_with_scope(action, options={})
controller_name = options.delete(:controller) || self.controller_name
if Devise.scoped_views
if self.class.scoped_views
begin
render :template => "#{controller_name}/#{devise_mapping.as}/#{action}"
rescue ActionView::MissingTemplate

View File

@ -219,6 +219,20 @@ class AuthenticationTest < ActionController::IntegrationTest
end
end
test 'renders the scoped view if turned on in an specific controller' do
begin
SessionsController.scoped_views = true
assert_raise Webrat::NotFoundError do
sign_in_as_user
end
assert_match /Special user view/, response.body
assert !PasswordsController.scoped_views
ensure
SessionsController.send :remove_instance_variable, :@scoped_views
end
end
test 'does not render the scoped view if turned off' do
swap Devise, :scoped_views => false do
assert_nothing_raised do

View File

@ -63,6 +63,15 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
end
end
test 'renders a scoped if scoped_views is set in the mailer class' do
begin
DeviseMailer.scoped_views = true
assert_equal user.email, mail.body
ensure
DeviseMailer.send :remove_instance_variable, :@scoped_views
end
end
test 'mailer sender accepts a proc' do
swap Devise, :mailer_sender => lambda { "another@example.com" } do
assert_equal ['another@example.com'], mail.from