Aktualisieren:
Dieses Problem wurde nicht richtig untersucht. Das eigentliche Problem liegt in render :json
.
Das erste Einfügen von Code in die ursprüngliche Frage liefert das erwartete Ergebnis. Es gibt jedoch immer noch eine Einschränkung. Siehe dieses Beispiel:
render :json => current_user
ist NICHT das gleiche wie
render :json => current_user.to_json
Das heißt, render :json
die to_json
dem Benutzerobjekt zugeordnete Methode wird nicht automatisch aufgerufen . In der Tat , wenn to_json
auf der überschrieben wird User
Modell render :json => @user
generiert die ArgumentError
unten beschrieben.
Zusammenfassung
# works if User#to_json is not overridden
render :json => current_user
# If User#to_json is overridden, User requires explicit call
render :json => current_user.to_json
Das alles kommt mir albern vor. Dies scheint mir zu sagen, dass render
nicht aufgerufen wird, Model#to_json
wenn der Typ :json
angegeben wird. Kann jemand erklären, was hier wirklich los ist?
Alle Genien, die mir dabei helfen können, können wahrscheinlich meine andere Frage beantworten: Wie erstelle ich eine JSON-Antwort, indem ich @ foo.to_json (Optionen) und @ bars.to_json (Optionen) in Rails kombiniere?
Ursprüngliche Frage:
Ich habe einige andere Beispiele auf SO gesehen, aber ich mache nicht das, wonach ich suche.
Ich versuche:
class User < ActiveRecord::Base
# this actually works! (see update summary above)
def to_json
super(:only => :username, :methods => [:foo, :bar])
end
end
Ich steige ArgumentError: wrong number of arguments (1 for 0)
ein
/usr/lib/ruby/gems/1.9.1/gems/activesupport-2.3.5/lib/active_support/json/encoders/object.rb:4:in `to_json
Irgendwelche Ideen?
quelle
username
,foo
oderbar
Methoden Argumente erwarten?username
ist kein Verfahren undfoo
undbar
keine Methoden erfordern. Ich habe meine Frage aktualisiert, um zu zeigen, wo der Fehler auftritt.Antworten:
Sie erhalten,
ArgumentError: wrong number of arguments (1 for 0)
weilto_json
mit einem Parameter, demoptions
Hash , überschrieben werden muss .Längere Erklärung
to_json
,as_json
und Rendering:In ActiveSupport 2.3.3
as_json
wurde hinzugefügt, um Probleme wie das aufgetretene zu beheben . Die Erstellung des JSON sollte vom Rendering getrennt sein des JSON getrennt sein.Jetzt wird jedes Mal, wenn
to_json
ein Objektas_json
aufgerufen wird, aufgerufen, um die Datenstruktur zu erstellen, und dann wird dieser Hash mithilfe von als JSON-Zeichenfolge codiertActiveSupport::json.encode
. Dies geschieht für alle Typen: Objekt, Zahl, Datum, Zeichenfolge usw. (siehe ActiveSupport-Code).ActiveRecord-Objekte verhalten sich genauso. Es gibt eine Standardimplementierung
as_json
, die einen Hash erstellt, der alle Attribute des Modells enthält. Sie solltenas_json
in Ihrem Modell überschreiben , um die gewünschte JSON-Struktur zu erstellen .as_json
verwendet genau wie der alteto_json
einen Options-Hash, in dem Sie Attribute und Methoden angeben können, die deklarativ eingeschlossen werden sollen.render :json => o
Kann in Ihrem Controller eine Zeichenfolge oder ein Objekt akzeptieren. Wenn es sich um eine Zeichenfolge handelt, wird sie als Antworttext durchlaufen, wenn es sich um ein Objektto_json
handelt, dasas_json
wie oben erläutert ausgelöst wird.Solange Ihre Modelle ordnungsgemäß mit
as_json
Überschreibungen dargestellt werden (oder nicht), sollte Ihr Controller-Code zur Anzeige eines Modells folgendermaßen aussehen:Die Moral der Geschichte lautet: Vermeiden Sie es,
to_json
direkt anzurufen , lassenrender
Sie das für Sie tun. Wenn Sie die JSON-Ausgabe optimieren müssen, rufen Sie aufas_json
.quelle
as_json
. Wie Sie in den ActiveRecord :: Serialization-Dokumenten ( api.rubyonrails.org/classes/ActiveRecord/… ) sehen können, gibt es hierfür nur sehr wenig (keine) Dokumentation. Ich werde es versuchen :)as_json
Dokumente!Wenn Sie in Rails 3 Probleme damit haben, überschreiben Sie
serializable_hash
stattas_json
. Dadurch erhalten Sie auch Ihre XML-Formatierung kostenlos :)Ich habe ewig gebraucht, um das herauszufinden. Hoffe das hilft jemandem.
quelle
serializable_hash
? Wenn ich es verwende, ändert es meine nachfolgende XML-Ausgabe vom Umschließen des Objekts mit seinem Namen (z. B. "Zitat" für ein Anführungszeichenobjekt "), um es stattdessen immer mit" <Hash> "zu umschließen.to_xml
Für Leute, die Benutzeroptionen nicht ignorieren, sondern auch ihre hinzufügen möchten:
Hoffe das hilft jedem :)
quelle
options
Hash mit,= {}
so dass es nicht erforderlich ist, wennÜberschreiben Sie nicht to_json, sondern as_json. Und von as_json rufen Sie an, was Sie wollen:
Versuche dies:
quelle
as_json
nur für ActiveResource?render :json => current_user
erhalte ich das erwartete Standardergebnis (alle Attribute für dasUser
Modell im JSON-Format). Wenn ich dieas_json
Methode zu meinemUser
Modell hinzufüge und dasselbe versuche, erhalte ich den Fehler :(