Railsアプリで、JSONを介してすべての記事のインデックスと完全な記事をレンダリングしようとしていますが、その方法を理解するのに少し問題があります。
これが私のコントローラーです。
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
応答でやりたいのは、次のようにすべての記事のインデックスを追加することです。
@index = Article.find(:all, :select => 'id, title')
私がそれを行うことができた唯一の方法は、インデックスと記事の両方をハッシュまたは配列に入れてから、それをJSONに入れることです。
@response = { :item => @article, :index => @index }
両方を含む完全なコード:
@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
:include
または:except
を指定して、正しくレンダリングできない場合を除いて、これで問題ありません。
あなたはあなたの質問の解決策をほのめかします。 JSONにレンダリングするハッシュを作成することをお勧めします。現在これを行うための好ましい方法は、as_jsonメソッドの実装を提供することです。 as_jsonは、エンコードするデータを含むハッシュを構築することにより、to_json出力をカスタマイズする正式な手段を提供します。
As_jsonとto_jsonがどのように相互作用するかについてのより徹底的な扱いは、 Jonathan Julianのウェブログ にあります。
明確にするために、上記のコードは:includeと:exceptで機能します。そして、作品とは、エラーをスローしないことを意味します。問題は、インデックス内のすべての記事に対するコメントが含まれていることです。インデックスにリストされている記事ではなく、:itemへのコメントのみを含めたいと思っています。
ネストをハッシュまたはOpenStructオブジェクトとして機能させることができませんでした。
:includeにネストするとエラーがスローされ、:exceptにネストしてもエラーはスローされませんが、何も除外されず、:created_atなどは引き続き表示されます。
...
@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
to_jsonには、名前を付けたメソッドの結果を含む:methodオプションがあります。そのモデルで、JSONに必要な追加データを返すメソッドを定義できます。
(回答を受け入れてください)
Nirvdrumが与えたリンクがあなたの答えを保持していると思います。誰もencode_json
について言及していないので、私は答えるだけです。
あなたの場合、あなたはas_json
だけを扱っているべきです。ハッシュを作成し(as_json
をさまざまに呼び出して)、それをrender :json => ...
に送信する(to_json
を呼び出さない)か、モデルにas_json
を実装してRailsすべての作業を行います。(ただし、前者が必要になると思います。)
レンダリングされた応答にいくつかの凝ったjsが本当に必要な場合は、クラスにencode_json
を実装できます(ここでも、to_json
ではありません)。例えば:
class JsEmptyClosure
def encode_json(*args)
"jQuery[\"noop\"] || function(){}"
end
def as_json(*args) self end
end
これは、有効なjsでto_json
に応答するようになります(ただし、実際にはjsonではないことに注意してください)。
:include
、:except
などを次のようにネストできるはずです。
:except => {:item => [ :created_at, :updated_at, :draft, :id, :publish ]}...
それが機能しない場合は、ハッシュではなくオブジェクト(OpenStructなど)にします。
-マーカス
質問をありがとう、私はいくつかの関連付けを持つモデルのjson形式をカスタマイズすることができます。
jsonをレンダリングします:@ posts.to_json(
:except => [:created_at、:updated_at、:user_id]、
:include => {
:user => {:only => [:email、:phone]}、
:location => {:only => [:title、:lat、:lon、:street、:city、:state、:zipcode]}、
:uploads => {:only => [:image]}
}
)
To_json出力で自動的に使用される代替ハッシュを返すようにattributesメソッドをオーバーロードすることをお勧めします。
class Article
def attributes
{ ... } # define your hash that you want to return at the '...'
end
end
私には、これはto_jsonを直接いじくり回すよりもはるかに簡単に思えます。