Update für Rails 4.2+
#respond_with
und ::respond_to
( nb class method) sind nicht mehr Teil von Rails . Sie wurden ab Rails 4.2 in das Juwel der Responder von Drittanbietern migriert ( Versionshinweise / Commit vom August 2014). Während Responder standardmäßig nicht in Rails enthalten sind, ist dies eine Abhängigkeit von Devise und daher in vielen Rails-Anwendungen verfügbar.
Die #respond_to
Instanzmethode ist jedoch immer noch Teil von Rails (5.2rc1 zum Zeitpunkt dieses Schreibens).
In der offiziellen Rails API-Dokumentation wird ActionController::MimeResponds
erläutert, wie dies #respond_to
funktioniert. Die originalen Rails Guides-Dokumentationskommentare für #respond_with
und ::respond_to
finden sich immer noch im Quellcode des Responders Gem .
Ursprüngliche Antwort
Der Code für die Responder basiert auf einer Klasse und einem Modul. MimeResponds, das in ActionController :: Base enthalten ist , der Klasse, von der Sie ApplicationController
erben. Dann gibt es ActionController :: Responder, der das Standardverhalten bei Verwendung von reply_with bereitstellt.
Standardmäßig ist das einzige Verhalten, das Rails in der Antwort bereitstellt, ein impliziter Versuch, eine Vorlage mit einem Namen zu rendern, der der Aktion entspricht. Alles darüber hinaus erfordert mehr Anweisungen innerhalb der Aktion oder einen benutzerdefinierten reply_to-Aufruf mit einem Block, um Antworten mit mehreren Formaten zu verarbeiten.
Da die meisten Controller ein recht häufiges Anpassungsmuster verwenden, bieten Responder eine zusätzliche Abstraktionsebene, indem sie mehr Standardverhalten einführen. Lesen Sie Aktionen, die to_xml / to_json für bestimmte Formate aufrufen, und Mutator-Aktionen, die dieselben bereitstellen, sowie Weiterleitungen für erfolgreiche Mutator-Aktionen.
Es gibt einige Möglichkeiten, das Verhalten von Respondern anzupassen, von subtilen Änderungen bis hin zum vollständigen Überschreiben oder Erweitern des Verhaltens.
Klassenstufe: respond_to
Hier geben Sie die Formate an, die der Responder verarbeiten soll. Die Formate können angepasst werden, auf welche Aktionen sie angewendet werden. Jedes Format kann mit separaten Aufrufen angegeben werden, sodass die Aktionen für jedes Format vollständig angepasst werden können.
# Responds to html and json on all actions
respond_to :html, :json
# Responds to html and json on index and show actions only.
respond_to :html, :json, :only => [:index,:show]
# Responds to html for everything except show, and json only for index, create and update
respond_to :html, :except => [:show]
respond_to :json, :only => [:index, :create, :update]
Klassenstufe: responder
Dies ist ein Klassenattribut, das den Responder enthält. Dies kann alles sein, was auf einen Anruf reagiert. Dies bedeutet, dass Sie einen proc / lambda oder eine Klasse verwenden können, die auf einen Anruf reagiert. Eine andere Alternative besteht darin, ein oder mehrere Module mit dem vorhandenen Responder zu mischen, um vorhandene Methoden zu überladen und das Standardverhalten zu verbessern.
class SomeController < ApplicationController
respond_to :json
self.responder = proc do |controller, resources, options|
resource = resources.last
request = controller.request
if request.get?
controller.render json: resource
elsif request.post? or request.put?
if resource.errors.any?
render json: {:status => 'failed', :errors => resource.errors}
else
render json: {:status => 'created', :object => resource}
end
end
end
end
Obwohl es einige interessante Edge-Anwendungsfälle geben kann, ist es wahrscheinlicher, dass das Erweitern oder Mischen von Modulen in den Standard-Responder häufiger vorkommt. In jedem Fall sind die relevanten Optionen die Ressourcen und Optionen, wie sie von from reply_with durchlaufen werden.
Instanzstufe: respond_with
Die hier aufgeführten Optionen werden an render oder redirect_to in Ihrem Controller übergeben, sind jedoch nur für Erfolgsszenarien enthalten. Bei GET-Aktionen sind dies die Renderaufrufe, bei anderen Aktionen die Optionen für die Umleitung. Die wahrscheinlich nützlichste davon ist die :location
Option, mit der dieser Umleitungspfad überschrieben werden kann, falls die Argumente für reply_with nicht ausreichen, um die richtige URL zu erstellen.
# These two are essentially equal
respond_with(:admin, @user, @post)
respond_with(@post, :location => admin_user_post(@user, @post)
# Respond with a 201 instead of a 200 HTTP status code, and also
# redirect to the collection path instead of the resource path
respond_with(@post, :status => :created, :location => posts_path)
# Note that if you want to pass a URL with a query string
# then the location option would be needed.
# /users?scope=active
respond_with(@user, :location => users_path(:scope => 'active'))
Alternativ bietet das Responder- Gem nicht nur einige Module zum Überschreiben einiger Standardverhalten. Es überschreibt den Standard-Responder mit einer anonymen Klasse, die den Standard-Responder erweitert, und bietet eine Methode auf Klassenebene zum Einmischen benutzerdefinierter Module in diese Klasse. Am nützlichsten ist hier der Flash-Responder, der einen Standardsatz von Flashs bereitstellt und die Anpassung an das I18n-System delegiert.config/locales/en.yml
standardmäßig .
Einige Beispiele für benutzerdefinierte Responder, die ich in früheren Projekten verwendet habe, umfassen einen Responder, der meine Ressourcen automatisch dekoriert und einen Standardsatz von Seitentiteln mit einer Oberfläche zum einfachen Anpassen oder Überschreiben des Seitentitels bereitstellt.
self.responder =
wie geraderesponder =
einem lokalen