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 Helpers def self.included(base) base.class_eval do unloadable helper_method :resource, :scope_name, :resource_name, :resource_class, :devise_mapping, :devise_controller? hide_action :resource, :scope_name, :resource_name, :resource_class, :devise_mapping, :devise_controller? skip_before_filter *Devise.mappings.keys.map { |m| :"authenticate_#{m}!" } before_filter :is_devise_resource? end 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 # Attempt to find the mapped route for devise based on request path def devise_mapping @devise_mapping ||= Devise::Mapping.find_by_path(request.path) end # Overwrites devise_controller? to return true def devise_controller? true end protected # Checks whether it's a devise mapped resource or not. def is_devise_resource? #:nodoc: raise ActionController::UnknownAction unless devise_mapping && devise_mapping.allows?(controller_name) end # Sets the resource creating an instance variable def resource=(new_resource) instance_variable_set(:"@#{resource_name}", new_resource) end # Build a devise resource without setting password and password confirmation fields. def build_resource self.resource ||= begin attributes = params[resource_name].try(:except, :password, :password_confirmation) resource_class.new(attributes || {}) end end # Helper for use in before_filters where no authentication is required. # # Example: # before_filter :require_no_authentication, :only => :new def require_no_authentication redirect_to after_sign_in_path_for(resource_name) if warden.authenticated?(resource_name) 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, now=false) flash_hash = now ? flash.now : flash flash_hash[key] = I18n.t(:"#{resource_name}.#{kind}", :scope => [:devise, controller_name.to_sym], :default => kind) end # Shortcut to set flash.now message. Same rules applied from set_flash_message def set_now_flash_message(key, kind) set_flash_message(key, kind, true) end # Render a view for the specified scope. Turned off by default. def render_with_scope(action) if Devise.scoped_views begin render :template => "sessions/#{devise_mapping.as}/#{action}" rescue ActionView::MissingTemplate render action end else render action end end end end end