Ich gehe den Leitfaden Erste Schritte mit Rails durch und wurde mit Abschnitt 6.7 verwechselt. Nach dem Generieren eines Gerüsts finde ich den folgenden automatisch generierten Block in meinem Controller:
def index
@posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @posts }
end
end
Ich möchte verstehen, wie der Block "reply_to" tatsächlich funktioniert. Welche Art von Variable ist Format? Sind .html- und .json-Methoden des Formatobjekts? Die Dokumentation für
ActionController::MimeResponds::ClassMethods::respond_to
beantwortet die Frage nicht.
ruby-on-rails
Cole
quelle
quelle
format.html
- kein Argument), werden Konventionen (basierend auf URL und HTTP-Verb) verwendet, um eine Ansicht auszuwählen (voraussichtlich HTML). Der Responder (Format) wird hier angewiesen, URLs mit der Endung .json durch Serialisierung in json zu rendern, anstatt Ansichten und Konventionen zu verwenden.Antworten:
Ich bin neu bei Ruby und stecke bei demselben Code fest. Die Teile, an denen ich aufgehängt wurde, waren etwas grundlegender als einige der Antworten, die ich hier fand. Dies kann jemandem helfen oder auch nicht.
respond_to
ist eine Methode in der OberklasseActionController
.do
bisend
, mit|format|
als Argument für den Block.format
Argument.http://api.rubyonrails.org/v4.1/classes/ActionController/Responder.html
Responder
enthält KEINE Methode für.html
oder.json
, aber wir nennen diese Methoden trotzdem! Dieser Teil warf mich für eine Schleife.method_missing
. Wenn Sie eine Methode aufrufen, die nicht existiert (wiejson
oderhtml
), ruft Rubymethod_missing
stattdessen die Methode auf.http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html
Responder
Klasse verwendet esmethod_missing
als eine Art Registrierung. Wenn wir 'json' aufrufen, weisen wir ihn an, auf Anfragen mit der Erweiterung .json zu antworten, indem er in json serialisiert. Wir müssenhtml
ohne Argumente aufrufen , um anzuweisen, dass HTML-Anforderungen standardmäßig behandelt werden sollen (unter Verwendung von Konventionen und Ansichten).Es könnte so geschrieben werden (mit JS-ähnlichem Pseudocode):
Dieser Teil verwirrte mich zum Teufel. Ich finde es immer noch nicht intuitiv. Ruby scheint diese Technik ziemlich oft anzuwenden. Die gesamte Klasse (
responder
) wird zur Methodenimplementierung. Um die Hebelwirkung nutzen zu könnenmethod_missing
, benötigen wir eine Instanz der Klasse. Daher müssen wir einen Rückruf übergeben, an den das methodenähnliche Objekt übergeben wird. Für jemanden, der seit 20 Jahren in C-ähnlichen Sprachen codiert, ist dies für mich sehr rückständig und nicht intuitiv. Nicht dass es schlecht wäre! Aber es ist etwas, was viele Leute mit diesem Hintergrund brauchen, um sich zurechtzufinden, und ich denke, es könnte das sein, wonach das OP gesucht hat.ps beachte, dass in RoR 4.2
respond_to
in Responder Gem extrahiert wurde .quelle
method_missing
, wenn man bedenkt, dass man ihm Argumente und einen Block übergeben kann!respond_to
in den Controllern zu erzeugen , ohne dass der Responder-Edelstein in der Gemfile vorhanden ist. Vielleicht wurde das bisschen darüberrespond_to
, in das Juwel der Responder extrahiert zu werden, geändert?Dies ist ein Block von Ruby-Code, der eine Rails-Hilfsmethode nutzt. Wenn Sie mit Blöcken noch nicht vertraut sind, werden Sie sie in Ruby häufig sehen.
respond_to
ist eine Rails-Hilfsmethode, die an die Controller-Klasse (oder besser gesagt an ihre Superklasse) angehängt ist. Es bezieht sich auf die Antwort, die an die Ansicht gesendet wird (die an den Browser gesendet wird).Der Block in Ihrem Beispiel formatiert Daten - indem Sie einen 'Format'-Parameter im Block übergeben -, die vom Controller an die Ansicht gesendet werden, wenn ein Browser eine Anfrage nach HTML- oder JSON-Daten stellt.
Wenn Sie sich auf Ihrem lokalen Computer befinden und Ihr Post-Gerüst eingerichtet haben, können Sie zu gehen
http://localhost:3000/posts
und alle Ihre Posts im HTML-Format sehen. Wenn Sie jedochhttp://localhost:3000/posts.json
Folgendes eingeben::, werden alle Ihre Beiträge in einem vom Server gesendeten JSON-Objekt angezeigt.Dies ist sehr praktisch, um Javascript-schwere Anwendungen zu erstellen, die json vom Server hin und her übertragen müssen. Wenn Sie möchten, können Sie problemlos eine JSON-API auf Ihrem Rails-Backend erstellen und nur eine Ansicht übergeben - wie die Indexansicht Ihres Post-Controllers. Dann könnten Sie eine Javascript-Bibliothek wie Jquery oder Backbone (oder beides) verwenden, um Daten zu bearbeiten und Ihre eigene Schnittstelle zu erstellen. Diese werden als asynchrone Benutzeroberflächen bezeichnet und erfreuen sich großer Beliebtheit (Google Mail ist eine davon). Sie sind sehr schnell und bieten dem Endbenutzer eine Desktop-ähnliche Erfahrung im Web. Dies ist natürlich nur ein Vorteil der Formatierung Ihrer Daten.
Die Rails 3-Schreibweise wäre folgende:
Indem Sie
respond_to :html, :xml, :json
an die Spitze der Klasse setzen, können Sie alle Formate deklarieren, die Ihr Controller an Ihre Ansichten senden soll.In der Controller-Methode müssen Sie dann nur noch mit (@whatever_object_you_have) antworten.
Es vereinfacht Ihren Code nur ein wenig mehr als das, was Rails automatisch generiert.
Wenn Sie mehr über das Innenleben wissen wollen ...
Soweit ich weiß, überprüft Rails die Objekte, um das tatsächliche Format zu bestimmen. Der Wert der 'Format'-Variablen basiert auf dieser Selbstbeobachtung. Schienen können mit ein paar Informationen eine ganze Menge tun. Sie wären überrascht, wie weit ein einfacher @post oder: post gehen wird.
Wenn ich zum Beispiel eine _user.html.erb-Teildatei hätte, die so aussieht:
_user.html.erb
Dann würde dies allein in meiner Indexansicht Rails wissen lassen, dass es notwendig ist, die "Benutzer" teilweise zu finden und alle "Benutzer" -Objekte zu durchlaufen:
index.html.erb
würde Rails wissen lassen, dass es notwendig ist, den 'Benutzer'-Teil zu finden und alle' Benutzer'-Objekte zu durchlaufen:
Sie können diesen Blog-Beitrag nützlich finden: http://archives.ryandaigle.com/articles/2009/8/6/what-s-new-in-edge-rails-cleaner-restful-controllers-w-respond_with
Sie können auch die Quelle lesen: https://github.com/rails/rails
quelle
respond_to
undrespond_with
eingeführt? Ich benutze Schienen 2.3.5 und ich bekommeNoMethodError (undefined method respond_to)
Soweit ich weiß, ist reply_to eine an den ActionController angehängte Methode, sodass Sie sie in jedem einzelnen Controller verwenden können, da alle vom ActionController erben. Hier ist die Rails-Methode "reply_to":
Sie passieren es einen Block , wie ich hier zeige:
Das | Format | Teil ist das Argument, das der Block erwartet, also können wir das innerhalb der Methode reply_to verwenden. Wie?
Wenn Sie bemerken, übergeben wir den Block mit einem vorangestellten & in der reply_to-Methode, und wir tun dies, um diesen Block als Proc zu behandeln. Da das Argument ".xml", ".html" hat, können wir dies als aufzurufende Methoden verwenden.
Grundsätzlich rufen wir in der Klasse "reply_to" die Methoden ".html, .xml, .json" für eine Instanz einer Responder-Klasse auf.
quelle
Um zu verstehen, was
format
ist, könnten Sie zuerst nach der Quelle suchenrespond_to
, aber schnell werden Sie feststellen, dass Sie wirklich den Code für retrieve_response_from_mimes suchen müssen .Von hier aus sehen Sie, dass der Block, an den
respond_to
(in Ihrem Code) übergeben wurde, tatsächlich aufgerufen und mit einer Instanz von Collector übergeben wird (auf die innerhalb des Blocks verwiesen wirdformat
). Collector generiert grundsätzlich Methoden (glaube ich beim Start von Rails) basierend auf den MIME-Typen, über die Rails Bescheid weiß.Also, ja, die Methoden sind
.html
und.json
sind (zur Laufzeit) in der Collector-format
Klasse (aka ) definiert.quelle
Die Meta-Programmierung hinter der Responder-Registrierung (siehe Antwort von Parched Squid) ermöglicht es Ihnen auch, solche raffinierten Dinge zu tun:
Die CSV-Zeile bewirkt, dass to_csv für jeden Beitrag aufgerufen wird, wenn Sie /posts.csv besuchen. Dies macht es einfach, Daten als CSV (oder ein anderes Format) von Ihrer Rails-Site zu exportieren.
Die js-Zeile bewirkt, dass eine Javascript-Datei /posts.js (oder /posts.js.coffee) gerendert / ausgeführt wird. Ich habe festgestellt, dass dies eine einfache Möglichkeit ist, eine Ajax-fähige Site mithilfe von Popup-Fenstern für die jQuery-Benutzeroberfläche zu erstellen.
quelle
Aus einem Java-POV ist das Format eine Implementierung einer anonymen Schnittstelle. Diese Schnittstelle verfügt über eine Methode, die für jeden MIME-Typ benannt ist. Wenn Sie eine dieser Methoden aufrufen (einen Block übergeben) und Rails der Meinung ist, dass der Benutzer diesen Inhaltstyp möchte, wird Ihr Block aufgerufen.
Die Wendung ist natürlich, dass dieses anonyme Klebeobjekt keine Schnittstelle implementiert - es fängt die Methodenaufrufe dynamisch ab und ermittelt, ob es sich um den Namen eines MIME-Typs handelt, den es kennt.
Persönlich finde ich es komisch: Der Block, den Sie übergeben, wird ausgeführt . Es wäre für mich sinnvoller, einen Hash von Formatbezeichnungen und -blöcken einzugeben. Aber - so wird es anscheinend in RoR gemacht.
quelle
Dies ist ein wenig veraltet, von Ryan Bigg macht einen tollen Job und erklärt dies hier:
http://ryanbigg.com/2009/04/how-rails-works-2-mime-types-respond_to
In der Tat könnte es ein bisschen detaillierter sein, als Sie gesucht haben. Wie sich herausstellt, ist hinter den Kulissen viel los, einschließlich der Notwendigkeit zu verstehen, wie die MIME-Typen geladen werden.
quelle
"Format" ist Ihr Antworttyp. Könnte zum Beispiel json oder html sein. Dies ist das Format der Ausgabe, die Ihr Besucher erhält.
quelle
Es gibt noch eine Sache, die Sie beachten sollten - MIME.
Wenn Sie einen MIME-Typ verwenden müssen und dieser standardmäßig nicht unterstützt wird, können Sie Ihre eigenen Handler in config / initializers / mime_types.rb registrieren:
Mime::Type.register "text/markdown", :markdown
quelle