2009-03-03 6 views
18

Ich bin auf der Suche nach einem Index aller Artikel zusammen mit einem vollständigen Artikel über JSON in meiner Rails App, aber ich habe ein wenig Mühe herauszufinden, wie es geht.Ruby on Rails Erweiterte JSON Serialisierung

Hier ist mein Controller jetzt:

if params[:id] 
    @article = Article.find(params[:id]) 
else 
    @article = Article.published.not_draft.by_recent.first 
end 

respond_to do |format| 

format.js { render :json => @article.to_json(
:except => [ :created_at, :updated_at, :draft, :id, :publish ], 
:include => { 
    :comments => { 
     :only => [:body] 
    } 
}), 
:callback => params[:callback]} 
end 

Was ich in der Antwort tun möchten ist, einen Index aller Artikel hinzufügen, etwa so:

@index = Article.find(:all, :select => 'id, title') 

Der einzige Weg, ich Ich war in der Lage, es zu tun, wird den Index und den Artikel in einen Hash oder ein Array setzen und dann zu JSON bringen.

@response = { :item => @article, :index => @index } 

Voll Code mit beiden:

@index = Article.find(:all, :select => 'id, title') 

if params[:id] 
    @article = Article.find(params[:id]) 
else 
    @article = Article.published.not_draft.by_recent.first 
end 

@response = { :item => @article, :index => @index } 

respond_to do |format| 

format.js { render :json => @response.to_json(), :callback => params[:callback]} 

end 

Dies wäre gut, außer ich jetzt nicht :include oder :except angeben können und bekommen es richtig zu machen.

:except => {:item => [ :created_at, :updated_at, :draft, :id, :publish ]}... 

Wenn das nicht funktioniert, machen es zu einem Objekt (beispielsweise ein OpenStruct) anstelle eines Hash:

Antwort

1

Sie sollten die :include, :except usw. wie so nisten können.

- Markus

2

Nur um klar zu sein den obigen Code mit den Werken: include und: Ausnahme. Und bei Werken meine ich, dass es keinen Fehler gibt. Das Problem ist, dass es Kommentare für jeden Artikel im Index enthält. Ich möchte nur Kommentare für den Artikel und nicht für die im Index aufgeführten Artikel einfügen.

Ich konnte nicht verschachteln, um als Hash oder OpenStruct-Objekt zu arbeiten.

Verschachteln auf: include wirft einen Fehler, verschachtelt auf: außer wirft keinen Fehler, aber nichts ist herausgefiltert,: created_at, etc. immer noch angezeigt.

... 

@response = { :item => @article, :index => @index } 

format.js { render :json => @response.to_json(
:except => {:item => [ :created_at, :updated_at, :draft, :id, :publish ]}, 
:include => { :item => { 
     :comments => { 
       :only => [:body] 
     } 
}}), 
:callback => params[:callback]} 
end 
1

to_json hat ein: Methode Option, die das Ergebnis jeder Methode enthält, die Sie nennen, könnten Sie eine Methode für das Modell definieren, die die zusätzlichen Daten, die Sie in Ihrem JSON wollen zurückgibt.

28

Sie deuten auf die Lösung in Ihrer Frage. Wahrscheinlich möchten Sie einen Hash erstellen, um ihn in JSON zu rendern. Der bevorzugte Weg, dies zu tun, besteht nun darin, eine Implementierung für die as_json-Methode bereitzustellen. as_json bietet eine formale Möglichkeit, die to_json-Ausgabe anzupassen, indem ein Hash erstellt wird, der die Daten enthält, die Sie verschlüsseln möchten.

Eine genauere Behandlung der Interaktion von as_json und to_json finden Sie unter Jonathan Julian's weblog.

1

(Bitte akzeptieren Sie eine Antwort)

denke ich, dass der Link, dass nirvdrum gab die Antwort hält. Ich antworte nur, weil niemand encode_json erwähnt hat. In Ihrem Fall sollten Sie nur mit as_json handeln.Entweder indem Sie einen Hash (mit verschiedenen Aufrufen an as_json) erstellen und diesen an render :json => ... senden (ohne den Anruf an to_json) oder indem Sie einfach as_json auf Ihrem Modell implementieren und Rails die ganze Arbeit erledigen lassen. (Aber ich vermute, dass Sie das erstere brauchen.)

Wenn Sie wirklich einige ausgefallene js in Ihrer gerenderten Antwort benötigen, können Sie encode_json in Ihren Klassen implementieren (wieder nicht to_json). Zum Beispiel:

class JsEmptyClosure 
    def encode_json(*args) 
    "jQuery[\"noop\"] || function(){}" 
    end 
    def as_json(*args) self end 
end 

Dies wird nun auf to_json mit gültigem js reagieren (aber beachten Sie, es nicht wirklich json ist).

0

Danke für die Frage, ich bin in der Lage, mein JSON-Format für ein Modell mit mehreren Assoziationen anzupassen.

json machen: @ posts.to_json (

: außer => [: created_at,: updated_at,: user_id],

: include => {

: user => {: only => [: E-Mail,: Telefon]},

: location => {: only => [: Titel,: lat,: lon,: Straße,: city,: state, : Postleitzahl] },

: Upload => {: Nur => [: image]}

}
)

0

I empfehlen würde die Attribute Verfahren Überlastung eines alternat Hash zurückzukehren, die automatisch in to_json Ausgang verwendet wird .

class Article 
    def attributes 
    { ... } # define your hash that you want to return at the '...' 
    end 
end 

Für mich scheint das viel einfacher als mit to_json direkt herumzualbern.