2014-02-14 14 views
5

Ich versuche, die Devise-Methode set_flash_message zu überschreiben. Die Dokumentation enthält Informationen zu override controllers for the various submodules.DeviseController-Basisklasse überschreiben - Rails 4, Devise 3

Allerdings ist diese besondere Methode innerhalb DeviseController, die Elternklasse Klasse aller Module befindet.

Die Dokumentation (sowohl Wiki als auch Inline) sagt nichts darüber aus, wie dies zu erreichen ist, also bin ich mir nicht sicher, wie ich am besten vorgehen soll. Ich glaube, der beste Weg wäre, die Klasse einfach wieder zu öffnen und die Methode nach Bedarf zu modifizieren, und dazu habe ich eine Datei in /lib platziert. Es scheint jedoch, dass es vor Devise geladen wird, was zu einem Fehler führt.

NameError in Devise::RegistrationsController#new 
undefined local variable or method `require_no_authentication' for #<Devise::RegistrationsController> 

Die komplexe Mutter Definition für DeviseController auch einen negativen Nettoeffekt sein, die kann:

class DeviseController < Devise.parent_controller.constantize 

Gedanken?

+0

Gibt es einen Grund, warum Sie nicht einfach die Funktionsdefinition in Ihrem Controller überschreiben können? –

+0

Es gibt keinen "meinen" Controller, Devise stellt die Controller für Sie bereit. Sie können sie überschreiben (siehe zweiter Link oben), aber das gilt nur für die Unterklassen, die die Module von Devise repräsentieren. –

+0

Wenn Sie Devise nicht abzweigen wollen, müssen Sie Ihre eigenen Controller erstellen und die Methode überschreiben. –

Antwort

1

Ich glaube, dies ist die Syntax Devise Controller außer Kraft zu setzen:

class RegistrationsController < Devise::RegistrationsController 

Wenn Sie Methode Fehler sind empfangen, müssen Sie sich daran erinnern wird nicht vollständig den Controller überschreiben - Ihre Methoden werden delegiert von die "main" ersinnen Controller, so dass Sie Dinge wie diese verwenden:

def method 
    super 
    your_code_here 
end 

aktualisieren

class SessionsController < DeviseController 
    prepend_before_filter :require_no_authentication, :only => [ :new, :create ] 
    prepend_before_filter :allow_params_authentication!, :only => :create 
    prepend_before_filter { request.env["devise.skip_timeout"] = true } 

    prepend_view_path 'app/views/devise' 

    # GET /resource/sign_in 
    def new 
    self.resource = resource_class.new(sign_in_params) 
    clean_up_passwords(resource) 
    respond_with(resource, serialize_options(resource)) 
    end 

    # POST /resource/sign_in 
    def create 
    self.resource = warden.authenticate!(auth_options) 
    set_flash_message(:notice, :signed_in) if is_navigational_format? 
    sign_in(resource_name, resource) 

    respond_to do |format| 
     format.json { render :json => {}, :status => :ok } 
     format.html { respond_with resource, :location => after_sign_in_path_for(resource) } 
    end 
    end 

    # DELETE /resource/sign_out 
    def destroy 
    redirect_path = after_sign_out_path_for(resource_name) 
    signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)) 
    set_flash_message :notice, :signed_out if signed_out && is_navigational_format? 

    # We actually need to hardcode this as Rails default responder doesn't 
    # support returning empty response on GET request 
    respond_to do |format| 
     format.all { head :no_content } 
     format.any(*navigational_formats) { redirect_to redirect_path } 
    end 
    end 


    protected 

    def sign_in_params 
    devise_parameter_sanitizer.sanitize(:sign_in) 
    end 

    def serialize_options(resource) 
    methods = resource_class.authentication_keys.dup 
    methods = methods.keys if methods.is_a?(Hash) 
    methods << :password if resource.respond_to?(:password) 
    { :methods => methods, :only => [:password] } 
    end 

    def auth_options 
    { :scope => resource_name, :recall => "#{controller_path}#new" } 
    end 
end 
+0

Wir haben erfolgreich die Devise-Controller mehrfach btw überschrieben :) –

+0

Wie ich habe, übergehe ich aber nicht die Devise-Controller, sondern die PARENT dieser Controller. Zeigen Sie mir ein Beispiel, das wie folgt instanziiert: 'Klasse CustomController> DeviseController'. Notieren Sie sich den Namen der übergeordneten Klasse. Ich will/muss nicht "RegistrationsController" oder "SessionsController" oder "ConfirmationsController" usw. überschreiben. –

+0

Hat ein Update von einer unserer älteren Apps veröffentlicht. Wahrscheinlich wird nicht funktionieren, aber es wird interessant sein zu sehen, was passiert! –

0

Devise.parent_controller ist in der Devise-Moduldefinition in devise/devise.rb definiert. Luckily, it has mattr_accessor declared, so können Sie den Wert selbst einstellen (der Standardwert ist "ApplicationController"). Es ist wahrscheinlich am sinnvollsten, dies einige Zeit in Ihrem Anwendungsinitialisierungsprozess zu tun, z. B. zusammen mit dem Rest der Devise-Konfiguration in initializers/devise.rb.

Verwandte Themen