使用Active Model Serializer,是否有一种简单而集成的方法可以在序列化集合时返回JSON“对象”(然后由客户端框架在javascript对象中转换)而不是JSON“数组”? (我引用了对象和数组,因为返回的JSON本质上是一个字符串)。
假设我有以下ArticleSerializer:
class ArticleSerializer < ActiveModel::Serializer
attributes :id, :body, :posted_at, :status, :teaser, :title
end
我从ArticlesController调用它:
class ArticlesController < ApplicationController
def index
@feed = Feed.new(articles: Article.all)
render json: @feed.articles, each_serializer: ArticleSerializer
end
end
有没有办法将选项传递给序列化程序,使其返回如下内容:
{"articles":
{
"1":{
...
},
"2":{
...
}
}
}
而不是
{"articles":
[
{
"id":"1",
...
},
{
"id":"2"
...
}
]
}
编辑:我想这篇文章中提出的方法(继承AMS ArraySerializer)可能会有所帮助(Active Model Serializer and Custom JSON Structure)
答案 0 :(得分:3)
您必须编写适合您格式的自定义适配器。
或者,您可以在将哈希值传递给render
之前修改哈希值。
如果你不介意迭代生成的哈希,你可以这样做:
ams_hash = ActiveModel::SerializableResource.new(@articles)
.serializable_hash
result_hash = ams_hash['articles'].map { |article| { article['id'] => article.except(:id) } }
.reduce({}, :merge)
或者,如果您希望这是默认行为,我建议切换到Attributes
适配器(与Json
适配器完全相同,除了没有文档根),并覆盖serializable_hash
方法,如下所示:
def format_resource(res)
{ res['id'] => res.except(:id) }
end
def serializable_hash(*args)
hash = super(*args)
if hash.is_a?(Array)
hash.map(&:format_resource).reduce({}, :merge)
else
format_resource(hash)
end
end
答案 1 :(得分:0)
不,从语义上讲,您将返回一组文章。哈希只是Javascript中的对象,所以你基本上想要一个带有1..n方法的对象,它返回每篇文章,但这没有多大意义。