mirror of
https://github.com/heartcombo/devise.git
synced 2026-04-28 03:00:29 -04:00
Get rid of InternalHelpers, refactor scoped views for more performant behavior.
This commit is contained in:
@@ -2,7 +2,7 @@ class Devise::ConfirmationsController < DeviseController
|
||||
# GET /resource/confirmation/new
|
||||
def new
|
||||
build_resource({})
|
||||
render_with_scope :new
|
||||
render :new
|
||||
end
|
||||
|
||||
# POST /resource/confirmation
|
||||
@@ -12,7 +12,7 @@ class Devise::ConfirmationsController < DeviseController
|
||||
if successfully_sent?(resource)
|
||||
respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name))
|
||||
else
|
||||
respond_with_navigational(resource){ render_with_scope :new }
|
||||
respond_with_navigational(resource){ render :new }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -25,7 +25,7 @@ class Devise::ConfirmationsController < DeviseController
|
||||
sign_in(resource_name, resource)
|
||||
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
|
||||
else
|
||||
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render_with_scope :new }
|
||||
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ class Devise::PasswordsController < DeviseController
|
||||
# GET /resource/password/new
|
||||
def new
|
||||
build_resource({})
|
||||
render_with_scope :new
|
||||
render :new
|
||||
end
|
||||
|
||||
# POST /resource/password
|
||||
@@ -14,7 +14,7 @@ class Devise::PasswordsController < DeviseController
|
||||
if successfully_sent?(resource)
|
||||
respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name))
|
||||
else
|
||||
respond_with_navigational(resource){ render_with_scope :new }
|
||||
respond_with_navigational(resource){ render :new }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,7 +22,7 @@ class Devise::PasswordsController < DeviseController
|
||||
def edit
|
||||
self.resource = resource_class.new
|
||||
resource.reset_password_token = params[:reset_password_token]
|
||||
render_with_scope :edit
|
||||
render :edit
|
||||
end
|
||||
|
||||
# PUT /resource/password
|
||||
@@ -35,7 +35,7 @@ class Devise::PasswordsController < DeviseController
|
||||
sign_in(resource_name, resource)
|
||||
respond_with resource, :location => after_sign_in_path_for(resource)
|
||||
else
|
||||
respond_with_navigational(resource){ render_with_scope :edit }
|
||||
respond_with_navigational(resource){ render :edit }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ class Devise::RegistrationsController < DeviseController
|
||||
# GET /resource/sign_up
|
||||
def new
|
||||
resource = build_resource({})
|
||||
respond_with_navigational(resource){ render_with_scope :new }
|
||||
respond_with_navigational(resource){ render :new }
|
||||
end
|
||||
|
||||
# POST /resource
|
||||
@@ -24,13 +24,13 @@ class Devise::RegistrationsController < DeviseController
|
||||
end
|
||||
else
|
||||
clean_up_passwords(resource)
|
||||
respond_with_navigational(resource) { render_with_scope :new }
|
||||
respond_with_navigational(resource) { render :new }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /resource/edit
|
||||
def edit
|
||||
render_with_scope :edit
|
||||
render :edit
|
||||
end
|
||||
|
||||
# PUT /resource
|
||||
@@ -50,7 +50,7 @@ class Devise::RegistrationsController < DeviseController
|
||||
respond_with resource, :location => after_update_path_for(resource)
|
||||
else
|
||||
clean_up_passwords(resource)
|
||||
respond_with_navigational(resource){ render_with_scope :edit }
|
||||
respond_with_navigational(resource){ render :edit }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ class Devise::SessionsController < DeviseController
|
||||
def new
|
||||
resource = build_resource
|
||||
clean_up_passwords(resource)
|
||||
respond_with_navigational(resource, stub_options(resource)){ render_with_scope :new }
|
||||
respond_with_navigational(resource, stub_options(resource)){ render :new }
|
||||
end
|
||||
|
||||
# POST /resource/sign_in
|
||||
|
||||
@@ -4,7 +4,7 @@ class Devise::UnlocksController < DeviseController
|
||||
# GET /resource/unlock/new
|
||||
def new
|
||||
build_resource({})
|
||||
render_with_scope :new
|
||||
render :new
|
||||
end
|
||||
|
||||
# POST /resource/unlock
|
||||
@@ -14,7 +14,7 @@ class Devise::UnlocksController < DeviseController
|
||||
if successfully_sent?(resource)
|
||||
respond_with({}, :location => new_session_path(resource_name))
|
||||
else
|
||||
respond_with_navigational(resource){ render_with_scope :new }
|
||||
respond_with_navigational(resource){ render :new }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,7 +26,7 @@ class Devise::UnlocksController < DeviseController
|
||||
set_flash_message :notice, :unlocked if is_navigational_format?
|
||||
respond_with_navigational(resource){ redirect_to new_session_path(resource) }
|
||||
else
|
||||
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render_with_scope :new }
|
||||
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,169 @@
|
||||
# All Devise controllers are inherited from here.
|
||||
class DeviseController < Devise.parent_controller.constantize
|
||||
include Devise::Controllers::InternalHelpers
|
||||
include Devise::Controllers::ScopedViews
|
||||
|
||||
helper DeviseHelper
|
||||
|
||||
helpers = %w(resource scope_name resource_name signed_in_resource
|
||||
resource_class devise_mapping devise_controller?)
|
||||
hide_action *helpers
|
||||
helper_method *helpers
|
||||
|
||||
prepend_before_filter :assert_is_devise_resource!
|
||||
respond_to *Mime::SET.map(&:to_sym) if mimes_for_respond_to.empty?
|
||||
|
||||
# Gets the actual resource stored in the instance variable
|
||||
def resource
|
||||
instance_variable_get(:"@#{resource_name}")
|
||||
end
|
||||
|
||||
# Proxy to devise map name
|
||||
def resource_name
|
||||
devise_mapping.name
|
||||
end
|
||||
alias :scope_name :resource_name
|
||||
|
||||
# Proxy to devise map class
|
||||
def resource_class
|
||||
devise_mapping.to
|
||||
end
|
||||
|
||||
# Returns a signed in resource from session (if one exists)
|
||||
def signed_in_resource
|
||||
warden.authenticate(:scope => resource_name)
|
||||
end
|
||||
|
||||
# Attempt to find the mapped route for devise based on request path
|
||||
def devise_mapping
|
||||
@devise_mapping ||= request.env["devise.mapping"]
|
||||
end
|
||||
|
||||
# Overwrites devise_controller? to return true
|
||||
def devise_controller?
|
||||
true
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Checks whether it's a devise mapped resource or not.
|
||||
def assert_is_devise_resource! #:nodoc:
|
||||
unknown_action! <<-MESSAGE unless devise_mapping
|
||||
Could not find devise mapping for path #{request.fullpath.inspect}.
|
||||
Maybe you forgot to wrap your route inside the scope block? For example:
|
||||
|
||||
devise_scope :user do
|
||||
match "/some/route" => "some_devise_controller"
|
||||
end
|
||||
MESSAGE
|
||||
end
|
||||
|
||||
# Returns real navigational formats which are supported by Rails
|
||||
def navigational_formats
|
||||
@navigational_formats ||= Devise.navigational_formats.select { |format| Mime::EXTENSION_LOOKUP[format.to_s] }
|
||||
end
|
||||
|
||||
def unknown_action!(msg)
|
||||
logger.debug "[Devise] #{msg}" if logger
|
||||
raise ActionController::UnknownAction, msg
|
||||
end
|
||||
|
||||
# Sets the resource creating an instance variable
|
||||
def resource=(new_resource)
|
||||
instance_variable_set(:"@#{resource_name}", new_resource)
|
||||
end
|
||||
|
||||
# Build a devise resource.
|
||||
def build_resource(hash=nil)
|
||||
hash ||= params[resource_name] || {}
|
||||
self.resource = resource_class.new(hash)
|
||||
end
|
||||
|
||||
# Helper for use in before_filters where no authentication is required.
|
||||
#
|
||||
# Example:
|
||||
# before_filter :require_no_authentication, :only => :new
|
||||
def require_no_authentication
|
||||
assert_is_devise_resource!
|
||||
return unless is_navigational_format?
|
||||
no_input = devise_mapping.no_input_strategies
|
||||
|
||||
authenticated = if no_input.present?
|
||||
args = no_input.dup.push :scope => resource_name
|
||||
warden.authenticate?(*args)
|
||||
else
|
||||
warden.authenticated?(resource_name)
|
||||
end
|
||||
|
||||
if authenticated
|
||||
resource = warden.user(resource_name)
|
||||
flash[:alert] = I18n.t("devise.failure.already_authenticated")
|
||||
redirect_to after_sign_in_path_for(resource)
|
||||
end
|
||||
end
|
||||
|
||||
# Helper for use after calling send_*_instructions methods on a resource.
|
||||
# If we are in paranoid mode, we always act as if the resource was valid
|
||||
# and instructions were sent.
|
||||
def successfully_sent?(resource)
|
||||
notice = if Devise.paranoid
|
||||
resource.errors.clear
|
||||
:send_paranoid_instructions
|
||||
elsif resource.errors.empty?
|
||||
:send_instructions
|
||||
end
|
||||
|
||||
if notice
|
||||
set_flash_message :notice, notice if is_navigational_format?
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the flash message with :key, using I18n. By default you are able
|
||||
# to setup your messages using specific resource scope, and if no one is
|
||||
# found we look to default scope.
|
||||
# Example (i18n locale file):
|
||||
#
|
||||
# en:
|
||||
# devise:
|
||||
# passwords:
|
||||
# #default_scope_messages - only if resource_scope is not found
|
||||
# user:
|
||||
# #resource_scope_messages
|
||||
#
|
||||
# Please refer to README or en.yml locale file to check what messages are
|
||||
# available.
|
||||
def set_flash_message(key, kind, options={}) #:nodoc:
|
||||
options[:scope] = "devise.#{controller_name}"
|
||||
options[:default] = Array(options[:default]).unshift(kind.to_sym)
|
||||
options[:resource_name] = resource_name
|
||||
message = I18n.t("#{resource_name}.#{kind}", options)
|
||||
flash[key] = message if message.present?
|
||||
end
|
||||
|
||||
def clean_up_passwords(object) #:nodoc:
|
||||
object.clean_up_passwords if object.respond_to?(:clean_up_passwords)
|
||||
end
|
||||
|
||||
def respond_with_navigational(*args, &block)
|
||||
respond_with(*args) do |format|
|
||||
format.any(*navigational_formats, &block)
|
||||
end
|
||||
end
|
||||
|
||||
def request_format
|
||||
@request_format ||= request.format.try(:ref)
|
||||
end
|
||||
|
||||
def is_navigational_format?
|
||||
Devise.navigational_formats.include?(request.format.try(:ref))
|
||||
end
|
||||
|
||||
# Override prefixes to consider the scoped view.
|
||||
def _prefixes
|
||||
@_prefixes ||= if self.class.scoped_views?
|
||||
super.unshift("#{devise_mapping.scoped_path}/#{controller_name}")
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -16,7 +16,6 @@ module Devise
|
||||
|
||||
module Controllers
|
||||
autoload :Helpers, 'devise/controllers/helpers'
|
||||
autoload :InternalHelpers, 'devise/controllers/internal_helpers'
|
||||
autoload :Rememberable, 'devise/controllers/rememberable'
|
||||
autoload :ScopedViews, 'devise/controllers/scoped_views'
|
||||
autoload :UrlHelpers, 'devise/controllers/url_helpers'
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
module Devise
|
||||
module Controllers
|
||||
# Those helpers are used only inside Devise controllers and should not be
|
||||
# included in ApplicationController since they all depend on the url being
|
||||
# accessed.
|
||||
module InternalHelpers #:nodoc:
|
||||
extend ActiveSupport::Concern
|
||||
include Devise::Controllers::ScopedViews
|
||||
|
||||
included do
|
||||
helper DeviseHelper
|
||||
|
||||
helpers = %w(resource scope_name resource_name signed_in_resource
|
||||
resource_class devise_mapping devise_controller?)
|
||||
hide_action *helpers
|
||||
helper_method *helpers
|
||||
|
||||
prepend_before_filter :assert_is_devise_resource!
|
||||
respond_to *Mime::SET.map(&:to_sym) if mimes_for_respond_to.empty?
|
||||
end
|
||||
|
||||
# Gets the actual resource stored in the instance variable
|
||||
def resource
|
||||
instance_variable_get(:"@#{resource_name}")
|
||||
end
|
||||
|
||||
# Proxy to devise map name
|
||||
def resource_name
|
||||
devise_mapping.name
|
||||
end
|
||||
alias :scope_name :resource_name
|
||||
|
||||
# Proxy to devise map class
|
||||
def resource_class
|
||||
devise_mapping.to
|
||||
end
|
||||
|
||||
# Returns a signed in resource from session (if one exists)
|
||||
def signed_in_resource
|
||||
warden.authenticate(:scope => resource_name)
|
||||
end
|
||||
|
||||
# Attempt to find the mapped route for devise based on request path
|
||||
def devise_mapping
|
||||
@devise_mapping ||= request.env["devise.mapping"]
|
||||
end
|
||||
|
||||
# Overwrites devise_controller? to return true
|
||||
def devise_controller?
|
||||
true
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Checks whether it's a devise mapped resource or not.
|
||||
def assert_is_devise_resource! #:nodoc:
|
||||
unknown_action! <<-MESSAGE unless devise_mapping
|
||||
Could not find devise mapping for path #{request.fullpath.inspect}.
|
||||
Maybe you forgot to wrap your route inside the scope block? For example:
|
||||
|
||||
devise_scope :user do
|
||||
match "/some/route" => "some_devise_controller"
|
||||
end
|
||||
MESSAGE
|
||||
end
|
||||
|
||||
# Returns real navigational formats which are supported by Rails
|
||||
def navigational_formats
|
||||
@navigational_formats ||= Devise.navigational_formats.select{ |format| Mime::EXTENSION_LOOKUP[format.to_s] }
|
||||
end
|
||||
|
||||
def unknown_action!(msg)
|
||||
logger.debug "[Devise] #{msg}" if logger
|
||||
raise ActionController::UnknownAction, msg
|
||||
end
|
||||
|
||||
# Sets the resource creating an instance variable
|
||||
def resource=(new_resource)
|
||||
instance_variable_set(:"@#{resource_name}", new_resource)
|
||||
end
|
||||
|
||||
# Build a devise resource.
|
||||
def build_resource(hash=nil)
|
||||
hash ||= params[resource_name] || {}
|
||||
self.resource = resource_class.new(hash)
|
||||
end
|
||||
|
||||
# Helper for use in before_filters where no authentication is required.
|
||||
#
|
||||
# Example:
|
||||
# before_filter :require_no_authentication, :only => :new
|
||||
def require_no_authentication
|
||||
assert_is_devise_resource!
|
||||
return unless is_navigational_format?
|
||||
no_input = devise_mapping.no_input_strategies
|
||||
|
||||
authenticated = if no_input.present?
|
||||
args = no_input.dup.push :scope => resource_name
|
||||
warden.authenticate?(*args)
|
||||
else
|
||||
warden.authenticated?(resource_name)
|
||||
end
|
||||
|
||||
if authenticated
|
||||
resource = warden.user(resource_name)
|
||||
flash[:alert] = I18n.t("devise.failure.already_authenticated")
|
||||
redirect_to after_sign_in_path_for(resource)
|
||||
end
|
||||
end
|
||||
|
||||
# Helper for use after calling send_*_instructions methods on a resource.
|
||||
# If we are in paranoid mode, we always act as if the resource was valid
|
||||
# and instructions were sent.
|
||||
def successfully_sent?(resource)
|
||||
notice = if Devise.paranoid
|
||||
resource.errors.clear
|
||||
:send_paranoid_instructions
|
||||
elsif resource.errors.empty?
|
||||
:send_instructions
|
||||
end
|
||||
|
||||
if notice
|
||||
set_flash_message :notice, notice if is_navigational_format?
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the flash message with :key, using I18n. By default you are able
|
||||
# to setup your messages using specific resource scope, and if no one is
|
||||
# found we look to default scope.
|
||||
# Example (i18n locale file):
|
||||
#
|
||||
# en:
|
||||
# devise:
|
||||
# passwords:
|
||||
# #default_scope_messages - only if resource_scope is not found
|
||||
# user:
|
||||
# #resource_scope_messages
|
||||
#
|
||||
# Please refer to README or en.yml locale file to check what messages are
|
||||
# available.
|
||||
def set_flash_message(key, kind, options={}) #:nodoc:
|
||||
options[:scope] = "devise.#{controller_name}"
|
||||
options[:default] = Array(options[:default]).unshift(kind.to_sym)
|
||||
options[:resource_name] = resource_name
|
||||
message = I18n.t("#{resource_name}.#{kind}", options)
|
||||
flash[key] = message if message.present?
|
||||
end
|
||||
|
||||
def clean_up_passwords(object) #:nodoc:
|
||||
object.clean_up_passwords if object.respond_to?(:clean_up_passwords)
|
||||
end
|
||||
|
||||
def respond_with_navigational(*args, &block)
|
||||
respond_with(*args) do |format|
|
||||
format.any(*navigational_formats, &block)
|
||||
end
|
||||
end
|
||||
|
||||
def request_format
|
||||
@request_format ||= request.format.try(:ref)
|
||||
end
|
||||
|
||||
def is_navigational_format?
|
||||
Devise.navigational_formats.include?(request.format.try(:ref))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -12,22 +12,6 @@ module Devise
|
||||
@scoped_views = value
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Render a view for the specified scope. Turned off by default.
|
||||
# Accepts just :controller as option.
|
||||
def render_with_scope(action, path=self.controller_path)
|
||||
if self.class.scoped_views?
|
||||
begin
|
||||
render :template => "#{devise_mapping.scoped_path}/#{path.split("/").last}/#{action}"
|
||||
rescue ActionView::MissingTemplate
|
||||
render :template => "#{path}/#{action}"
|
||||
end
|
||||
else
|
||||
render :template => "#{path}/#{action}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,7 +1,6 @@
|
||||
require 'test_helper'
|
||||
|
||||
class MyController < ApplicationController
|
||||
include Devise::Controllers::InternalHelpers
|
||||
class MyController < DeviseController
|
||||
end
|
||||
|
||||
class HelpersTest < ActionController::TestCase
|
||||
|
||||
Reference in New Issue
Block a user