2015-06-15 13 views
8

Ich würde wissen, wie die load_and_authorize_resource innerhalb arbeitet. Ich suchte die GitHub-Seite Link und versuchte zu verstehen, aber ich habe nichts nützliches gefunden. Ich verstehe nur, dass load_and_authorize_resource ist wie ein before_filter und es lädt (in gewisser Weise) die Fähigkeit, die wir geschrieben haben in fähigkeit.rbCanCan Erklärung von load_and_authorize_resource

Ich würde besser wissen, wie das möglich ist. Ich meine, ich möchte nicht ALLE Edelsteine ​​studieren, aber ich möchte nur sehen, wie kann ich die Fähigkeit einer Ressource in einem Controller laden und wenn die load_and_authorize_resource ist wirklich eine Art von vor_filter.

Antwort

11

Haftungsausschluss: Aus Gründen der Einfachheit lasse ich einige Aufrufe zu kurzen inneren Methoden absichtlich aus. Die vollständige Kette des Aufrufs kann erhalten werden, indem man der Methodendefinition load_and_authorize_resource folgt und so weiter.

Wie in der Dokumentation angegeben, load_and_authorize_resource einrichtet ein before_filter ...

# cancan/lib/cancan/controller_additions.rb 
def load_and_authorize_resource(*args) 
    cancan_resource_class.add_before_filter(self, :load_and_authorize_resource, *args) 
end 

... die zwei Methoden aufruft: load_resource und authorize_resource.

# cancan/lib/cancan/controller_resource.rb 
def load_and_authorize_resource 
    load_resource 
    authorize_resource 
end 

Um die Idee ihres Verhaltens zu bekommen, werden wir uns beide genau anschauen.

Basierend auf params Hash, die auf Ihre Controller-Aktion übergeben wurde, macht load_resource eine Entscheidung darüber, ob es eine neue Instanz einer Klasse erhalten sollte (z Post.new) oder find eine bestimmte Instanz basierend auf params[:id] (z Post.find(params[:id])). Diese Instanz (oder eine Sammlung von Instanzen für Aktionen wie index) wird der entsprechenden Instanzvariable Ihrer Controller-Aktion zugewiesen.

# cancan/lib/cancan/controller_resource.rb 
def load_resource 
    unless skip?(:load) 
    if load_instance? 
     # here you have obtained your object, e.g. Post with id=5 
     # and placed it into cancan resource_instance variable. 
     # it has automatically set up @post instance variable for you 
     # in your action 
     self.resource_instance ||= load_resource_instance 
    elsif load_collection? 
     self.collection_instance ||= load_collection 
    end 
    end 
end 

Später wird authorize_resource aufgerufen. Seine innere Logik-Syntax sollte Ihnen vertraut sein: Das Überprüfen von Fähigkeiten mit den Händen sieht genauso aus wie das, was innerhalb dieser Methode geschieht. Grundsätzlich nehmen Sie eine resource_instance, die im vorherigen Schritt erhalten wurde, params[:action] das ist der Name einer aktuellen Aktion, und prüfen, ob bestimmte Aktion für bestimmte Objekte zugegriffen werden kann.

# cancan/lib/cancan/controller_resource.rb 
def authorize_resource 
    unless skip?(:authorize) 
    # similar to what happens when you call authorize!(:show, @post) 
    @controller.authorize!(authorization_action, resource_instance || resource_class_with_parent) 
    end 
end 

Solange Ausnahmen innerhalb von before_filter stoppt Controller-Aktion von gerade ausgeführt erheben, andernfalls Genehmigung passieren hier bringt Sie zu Ihrer Anwendung zu Hause URL weitergeleitet, gezeigt 500 Fehlerseite oder Verhalten Was auch immer Sie definiert für CanCan::AccessDenied Handhabung.

Auf der anderen Seite wird Ihr Aktionscode ausgeführt, wenn Sie die Autorisierung erfolgreich bestanden haben. Jetzt haben Sie Zugriff auf Instanzvariable (z. B. @post), die von CanCan unter load_resource Schritt eingerichtet wurde.

+0

danke! du hilfst mir sehr! – Vito

+1

Woher weiß es, ob eine Sammlung abgerufen oder eine Instanz erstellt oder geladen werden soll? – mwfearnley