我希望在我的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
并让它正确呈现。
答案 0 :(得分:28)
您在提问中提示解决方案。您最有可能想要构建一个哈希来呈现给JSON。现在这样做的首选方法是为as_json方法提供一个实现。 as_json提供了一种通过构建包含您要编码的数据的哈希来自定义to_json输出的正式方法。
可以在Jonathan Julian's weblog上找到有关as_json和to_json如何互动的更全面的处理方法。
答案 1 :(得分:2)
为了清楚上面的代码适用于:include和:except。通过工作,我的意思是它不会引发错误。问题是它包含对索引中每篇文章的评论。我只想包含对项目的评论,而不是索引中列出的任何文章。
我无法将嵌套作为哈希或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
答案 2 :(得分:1)
你应该能够像{I}}那样嵌套:include
,:except
等:
:except => {:item => [ :created_at, :updated_at, :draft, :id, :publish ]}...
如果这不起作用,请将其设为对象(例如OpenStruct)而不是散列。
- 马库斯
答案 3 :(得分:1)
to_json有一个:method选项,其中包含您命名的任何方法的结果,您可以在该模型上定义一个方法,该方法返回您在JSON中所需的其他数据。
答案 4 :(得分:1)
(请接受回答)
我认为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)。
答案 5 :(得分:0)
感谢您提出的问题,我可以为具有多个关联的模型自定义我的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, :邮政编码]},
:uploads => {:only => [:图像]}
}
)
答案 6 :(得分:0)
我建议重载属性方法以返回将在to_json输出中自动使用的alternat哈希。
class Article
def attributes
{ ... } # define your hash that you want to return at the '...'
end
end
对我来说,这似乎比直接使用to_json更简单。