活动模型序列化程序,没有数组根,但是子根

时间:2014-05-05 23:57:34

标签: ruby-on-rails active-model-serializers

我已将活动模型序列化程序gem添加到项目中并且它破坏了一堆东西,我们的一个api有一个非常特定的格式,我需要保留,不幸的是它似乎没有我可以得到遗产行为。

#Models
class Parent < ActiveRecord::Base
  attr_accessable, :id, :name, :options
  has_many :children
end

class Child < ActiveRecord::Base
  attr_accessable, :id, :name
end

#Controller
class ParentsController < ApplicationController

  respond_to :json

  def index
    #Was
    @parents = Parent.all
    respond_with @parents, :include => [:children]

    #Is (and is not working)
    @parents = Parent.includes(:children)
    respond_with @parents, each_serializer: ::ParentsSerializer, root: false  #Not working
  end
...
end

#Serializer
class ParentSerializer < ActiveModel::Serializer
  attrs = Parent.column_names.map(&:to_sym) - [:options]
  attributes(*attrs)
  has_many :children

  def filter(keys)
    keys.delete :children unless object.association(:children).loaded?
    keys.add :options
    keys
  end
end

期望输出

[
  {
    "parent": {
      "id": 1,
      "name": "Uncle",
      "options":"Childless, LotsOfLoot",
      "children": []
    }
  },
  {
    "parent": {
      "id": 2,
      "name": "Mom",
      "options":"<3 Gossip, SoccerMom",
      "children": [
        {
          "child": {
            "id": 10,
            "name": "susy"
          }
        },
        {
          "child": {
            "id": 11,
            "name": "bobby"
          }
        }
      ]
    }
  }
]

我需要的是json的格式化方式,它不包括顶级根,但确实包含子根...我知道我可以使用类似Rabl的东西,但如果有一个使用ActiveModel Serializers进行简单干净的方式,这会更好。

1 个答案:

答案 0 :(得分:0)

令我惊讶的是,似乎没有直接支持这一点,我迷失了你要删除的内容以添加它。但是,解决方法并不严重 - 只需定义自定义children方法:

#Serializer
class ParentSerializer < ActiveModel::Serializer
  attrs = Parent.column_names.map(&:to_sym) - [:options]
  attributes(*attrs)
  has_many :children

  def filter(keys)
    keys.delete :children unless object.association(:children).loaded?
    keys.add :options
    keys
  end

  def children
    object.children.collect{|c| ChildSerializer.new(c, scope).as_json(root: :child)}
  end
end

您正在使用ArraySerializer方法进行children的工作,但如果没有AM :: S的支持,我不确定是否更清洁。