Rails ActiveModel :: Serializers中的JSON API样式边加载

wil*_*_wi 6 json ruby-on-rails serializer ruby-on-rails-4

我正在尝试使用AM :: Serializer 构建JSON API样式API.我遇到了侧载问题.

我希望能够构建如下所示的JSON:

{
    "primaries": [{
        "id": 123,
        "data": "Hello world.",
        "links": {
            "secondaries": [ 1, 2, 3 ]
        }
    }],
    "linked" : {
        "secondaries": [
            {
                "id": 1,
                "data": "test1"
            },
            {
                "id": 2,
                "data": "test2"
            },
            {
                "id": 3,
                "data": "test3"
            }
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

我能够提出的代码如下:

class PrimarySerializer < ActiveModel::Serializer
  attributes :id, :data

  has_many :secondaries, key: :secondaries, root: :secondaries
  embed :ids, include: true
end
Run Code Online (Sandbox Code Playgroud)

这会生成如下所示的JSON:

{
    "primaries": [{
        "id": 123,
        "data": "Hello world.",
        "secondaries": [ 1, 2, 3 ]
    }],
    "secondaries": [
        {
            "id": 1,
            "data": "test1"
        },
        {
            "id": 2,
            "data": "test2"
        },
        {
            "id": 3,
            "data": "test3"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

有没有办法覆盖的元件中的位置secondaries和侧载secondaries,使得他们生活在子节点linklinked

上面的代码是实际代码的抽象,可能无法正常工作.希望它充分说明了这一点.

谢谢!

Mar*_*ars 2

ActiveModel 序列化器可以做到这一点。问题在于内置关联方法的限制性太大。相反,您必须手动构建links&linked部件。

(这个答案指的是ActiveModel Serializers 的稳定 0.8.1 版本

这是带有完整 JSON-API 解决方案的要点https://gist.github.com/mars/97a637560109b8ddfb27

例子:

class ExampleSerializer < JsonApiSerializer # see Gist for superclass
  attributes :id, :name, :links

  def links
    {
      things: object.things.map(&:id),
      whatzits: object.whatzits.map(&:id)
    }
  end

  def as_json(*args)
    hash = super(*args)

    hash[:linked] = {
      things: ActiveModel::ArraySerializer.new(
          object.things,
          each_serializer: ThingsSerializer
        ).as_json,
      whatzits: ActiveModel::ArraySerializer.new(
          object.whatzits,
          each_serializer: WhatzitsSerializer
        ).as_json
    }

    hash
  end

end
Run Code Online (Sandbox Code Playgroud)