【问题标题】:Rails Serialization - fast_jsonapi / active_model_serializersRails 序列化 - fast_jsonapi / active_model_serializers
【发布时间】:2020-04-15 19:32:10
【问题描述】:

在加入 fast_jsonapi / active_model_serializers 来构建 API 时我有点迷失了。我已经掌握了基础知识,但似乎停留在自定义解决方案上。

我有这个作为序列化程序:

class AreaSerializer
  include FastJsonapi::ObjectSerializer
  attributes :id, :name, :cost_center, :notes
  has_many :children
end

在我的区域模型中,我有:

  has_many :children, -> { Area.where(ancestry: id) }

我的控制器看起来像:

class Api::V1::AreasController < ApiController

  def index
    render json: AreaSerializer.new(Area.root).serialized_json
  end

end

区域嵌套在具有祖先宝石的层次结构中。输出是:

{
"data": [{
    "id": "1",
    "type": "area",
    "attributes": {
        "id": 1,
        "name": "Calgary",
        "cost_center": "123456",
        "notes": ""
    },
    "relationships": {
        "children": {
            "data": [{
                "id": "3",
                "type": "child"
            }]
        }
    }
}, {
    "id": "2",
    "type": "area",
    "attributes": {
        "id": 2,
        "name": "Edmonton",
        "cost_center": "78946",
        "notes": ""
    },
    "relationships": {
        "children": {
            "data": []
        }
    }
}]

}

我正在寻找这样的输出:

{
"data": [{
    "id": "1",
    "type": "area",
    "attributes": {
        "id": 1,
        "name": "Calgary",
        "cost_center": "123456",
        "notes": ""
    },
    "relationships": {
        "areas": {
            "data": [{
                "id": "3",
                "type": "area",
                "attributes": {
                    "id": 3,
                    "name": "Child Area",
                    "cost_center": "123456",
                    "notes": ""
                }
            }]
        }
    }
}, {
    "id": "2",
    "type": "area",
    "attributes": {
        "id": 2,
        "name": "Edmonton",
        "cost_center": "78946",
        "notes": ""
    }
}]

}

这个想法是嵌套关系显示细节等。

【问题讨论】:

    标签: ruby-on-rails json serialization fastjsonapi


    【解决方案1】:

    我刚开始在我的 rails 项目中使用fast_jsonapi

    fast_jsonapi 坚持JSON:API spec which you can see here.

    因此,您将无法使用关系辅助函数 (:has_many, :belongs_to) 来实现所需的输出,即在 relationships 键内嵌套 area 的属性。

    "relationships": {
            "areas": {
                "data": [{
                    "id": "3",
                    "type": "area",
                    "attributes": { // nesting attributes of area
                        "id": 3,
                        "name": "Child Area",
                        "cost_center": "123456",
                        "notes": ""
                    }
                }]
            }
        }
    

    JSON:API 指定:

    为了减少 HTTP 请求的数量,服务器可以允许响应 包括相关资源以及请求的主要资源 资源。此类响应称为“复合文档”。

    因此,您将在名为 included 的键中拥有 area 的属性。

    为了在您的响应中获得included 键,您需要在控制器中向序列化程序提供options 哈希。

    我不太了解您的模型Area 关系,但假设Area 有许多SubArea

    class Api::V1::AreasController < ApiController
    
      def index
        // serializer options
        options = {
          include: [:sub_area],
          collection: true
        }
        render json: AreaSerializer.new(Area.root, options).serialized_json
      end
    
    end
    

    【讨论】:

      【解决方案2】:

      您不能在 fast_jsonapi 中使用关联。以嵌套格式获取响应。您需要添加方法并需要创建另一个序列化程序。

      class AreaSerializer
        include FastJsonapi::ObjectSerializer
      
        set_type 'Area'
      
        attributes :id, :name, :cost_center, :notes
      
       attribute :childrens do |area, params|
           ChildrenSerializer.new(area.childrens, {params: 
           params})
        end
      end
      
      class ChildrenSerilizer
         include FastJsonapi::ObjectSerializer
          set_type 'Area'
          attributes :id, :name ... 
      end
      

      【讨论】:

        【解决方案3】:

        我开始使用上面列出的技术,但最终分叉并重新编写了 jsonapi-serializer gem,因此它允许嵌套(最多 4 层深度)并取消了拥有 relationshipsattributes 键的概念.我也很沮丧,它只输出 ID 和 TYPE 键,其中 TYPE 大多数时候是多余的,因为作为示例,对象通常在数组中保持相同的类,人们很少使用真正的多态性(尽管它仍然支持这一点并输出 ID /type 表示多态关系)。

        我重写的最佳部分可能是它允许通过新的fields 输入在 json 密钥树中的任何位置进行确定性字段选择。

        https://github.com/rubesMN/jsonapi-serializer

        【讨论】:

          猜你喜欢
          • 2017-07-17
          • 2020-03-20
          • 2023-04-06
          • 2019-04-16
          • 2017-03-03
          • 2016-07-16
          • 1970-01-01
          • 1970-01-01
          • 2014-02-11
          相关资源
          最近更新 更多