我迷上了fast_jsonapi / active_model_serializers来构建API。我掌握了基础知识,但似乎停留在自定义解决方案上。
我有这个作为序列化器:
类AreaSerializer 包括FastJsonapi :: ObjectSerializer 属性:id,:name,:cost_center,:notes has_many:儿童 结束
在我的区域模型中,我有:
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":""}}]}
这个想法就是嵌套关系显示细节的地方。
答案 0 :(得分:0)
我刚刚开始在Rails项目中使用fast_jsonapi
。
fast_jsonapi
遵守JSON:API spec which you can see here.
因此,您将无法使用关系帮助器函数(:has_many,:belongs_to)实现所需的输出,该输出将relationships
键内的区域属性嵌套。
"relationships": {
"areas": {
"data": [{
"id": "3",
"type": "area",
"attributes": { // nesting attributes of area
"id": 3,
"name": "Child Area",
"cost_center": "123456",
"notes": ""
}
}]
}
}
JSON:API指定:
为了减少HTTP请求的数量,服务器可以允许响应 包括相关资源以及请求的主要资源 资源。这样的响应称为“复合文档”。
因此,您将在名为area
的键中拥有included
的属性。
为了获得响应中的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
答案 1 :(得分:0)
您不能在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
答案 2 :(得分:0)
我开始使用上面列出的技术,但最终分叉并重新编写了 jsonapi-serializer gem,因此它允许嵌套(最多 4 层深)并消除了 relationships
和 {{ 1}} 键。我也很沮丧它只输出 ID 和 TYPE 键,其中 TYPE 大多数时候是多余的,因为对象通常在数组中保持相同的类作为示例,人们很少使用真正的多态性(尽管它仍然支持这个并输出 ID /type 用于多态关系)。
我重写的最好部分可能是它允许通过新的 attributes
输入在 json 密钥树中的任何位置进行确定性字段选择。