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.
danke! du hilfst mir sehr! – Vito
Woher weiß es, ob eine Sammlung abgerufen oder eine Instanz erstellt oder geladen werden soll? – mwfearnley