Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveModel::Serializer::CollectionSerializer

I'm using Active Model Serializers v0.10.0.rc4

I want to produce json that looks like this:

{
  "posts": [
    { "post": {"id": 2, "name": "foo"} },
    { "post": {"id": 3, "name": "bar"} }
  ],
  "next_page": 3
}

I know the basic:

render json: posts, each_serializer: PostSerializer

will produce json like this:

[
  {"id": 2, "name": "foo"}
  {"id": 3, "name": "bar"}
]

I have attempted the following:

controller:

render json: posts, serializer: PostsSerializer

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

But this produces json like this:

{
  "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
}

Anyone know how I can achieve the desired schema?

like image 612
b73 Avatar asked Oct 19 '22 13:10

b73


1 Answers

In the end I didn't use CollectionSerializer. This is what I went with instead:

controller:

render json: posts, serializer: PostsSerializer

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

Specifying the json adapter ensured that the post elements had the required root node.

Whilst I appreciate that having a root node specified for array items may not be conventional, it was required for this api.

like image 55
b73 Avatar answered Oct 21 '22 06:10

b73