如何使用 Active Model ArraySerializer return a json "object" 而不是 json "array"?
How to return a json "object" instead of a json "array" with Active Model ArraySerializer?
使用 Active Model Serializer,是否有一种简单且集成的方法来 return a JSON "object"(然后将其转换为 javascript 对象客户端框架)而不是 JSON "array" 序列化集合时? (我引用对象和数组,因为 returned 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
有没有一种方法可以将选项传递给序列化程序,使其 return 类似于:
{"articles":
{
"1":{
...
},
"2":{
...
}
}
}
而不是
{"articles":
[
{
"id":"1",
...
},
{
"id":"2"
...
}
]
}
编辑:我想这个 post(AMS ArraySerializer 的子类)中提出的方法可能会有所帮助 (Active Model Serializer and Custom JSON Structure)
不,从语义上讲,您返回的是一组文章。哈希只是 Javascript 中的对象,因此您本质上想要一个具有 1..n 方法的对象,每个文章 returns,但这没有多大意义。
您必须编写一个自定义适配器来适应您的格式。
或者,您可以在将哈希传递给 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
使用 Active Model Serializer,是否有一种简单且集成的方法来 return a JSON "object"(然后将其转换为 javascript 对象客户端框架)而不是 JSON "array" 序列化集合时? (我引用对象和数组,因为 returned 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
有没有一种方法可以将选项传递给序列化程序,使其 return 类似于:
{"articles":
{
"1":{
...
},
"2":{
...
}
}
}
而不是
{"articles":
[
{
"id":"1",
...
},
{
"id":"2"
...
}
]
}
编辑:我想这个 post(AMS ArraySerializer 的子类)中提出的方法可能会有所帮助 (Active Model Serializer and Custom JSON Structure)
不,从语义上讲,您返回的是一组文章。哈希只是 Javascript 中的对象,因此您本质上想要一个具有 1..n 方法的对象,每个文章 returns,但这没有多大意义。
您必须编写一个自定义适配器来适应您的格式。
或者,您可以在将哈希传递给 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