ActiveModel :: Serializer :: CollectionSerializer

b73*_*b73 5 ruby active-model-serializers ruby-on-rails-4

我正在使用Active Model Serializers v0.10.0.rc4

我想产生看起来像这样的json:

{
  "posts": [
    { "post": {"id": 2, "name": "foo"} },
    { "post": {"id": 3, "name": "bar"} }
  ],
  "next_page": 3
}
Run Code Online (Sandbox Code Playgroud)

我知道基本的:

render json: posts, each_serializer: PostSerializer
Run Code Online (Sandbox Code Playgroud)

将产生这样的json:

[
  {"id": 2, "name": "foo"}
  {"id": 3, "name": "bar"}
]
Run Code Online (Sandbox Code Playgroud)

我尝试了以下操作:

控制器:

render json: posts, serializer: PostsSerializer
Run Code Online (Sandbox Code Playgroud)

posts_serializer:

class PostsSerializer < ActiveModel::Serializer
  attributes :posts, :next_page

  def posts
    ActiveModel::Serializer::CollectionSerializer.new(object,
      each_serializer: PostSerializer,
      root: "post"
    )
  end

  def next_page
    3 
  end
end
Run Code Online (Sandbox Code Playgroud)

但这会产生如下的json:

{
  "posts": [
    {
      "object": {"id": 2, "name": "foo"},
      "instance_options": {"each_serializer: {}", "root": "post" }
    },
    {
      "object": {"id": 3, "name": "bar"},
      "instance_options": {"each_serializer: {}", "root": "post" }
    },
  ],
  "next_page": 3
}
Run Code Online (Sandbox Code Playgroud)

有人知道我如何实现所需的架构吗?

b73*_*b73 3

最终我没有使用CollectionSerializer。这就是我所选择的:

控制器:

render json: posts, serializer: PostsSerializer
Run Code Online (Sandbox Code Playgroud)

posts_serializer:

class PostsSerializer < ActiveModel::Serializer
  attributes :posts, :next_page

  def posts
    object.map do |p|
      ActiveModel::SerializableResource.new(p, adapter: :json)
    end
  end

  def next_page
    # todo
  end
end
Run Code Online (Sandbox Code Playgroud)

指定json适配器可确保post元素具有所需的根节点。

虽然我意识到为数组项指定根节点可能不常见,但这是此 api 所必需的。