Ruby on Rails高级JSON序列化
我想在我的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抛出错误,嵌套在:除了不抛出错误,但没有任何过滤掉,: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
您应该能够嵌套:include
, :except
等,如下所示:
:except => {:item => [ :created_at, :updated_at, :draft, :id, :publish ]}...
如果这不起作用,请将其设为对象(例如OpenStruct)而不是哈希。
– 马库斯
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)。
谢谢你的问题,我能够为具有多个关联的模型自定义我的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输出中自动使用的alternat哈希。
class Article def attributes { ... } # define your hash that you want to return at the '...' end end
对我来说,这似乎比直接使用to_json更简单。