我使用的是Rails 4.2.1
和active_model_serializers 0.10.0.rc2
我是API的新手,选择active_model_serializers
是因为它似乎正在成为rails的标准(尽管我并不反对使用RABL
或其他序列化程序)。
我遇到的问题是,我似乎不能在多级关系中包含各种属性。例如,我有:
Projects
class ProjectSerializer < ActiveModel::Serializer
attributes :id,
:name,
:updated_at
has_many :estimates, include_nested_associations: true
end
估计
class EstimateSerializer < ActiveModel::Serializer
attributes :id,
:name,
:release_version,
:exchange_rate,
:updated_at,
:project_id,
:project_code_id,
:tax_type_id
belongs_to :project
belongs_to :project_code
belongs_to :tax_type
has_many :proposals
end
Proposals
class ProposalSerializer < ActiveModel::Serializer
attributes :id,
:name,
:updated_at,
:estimate_id
belongs_to :estimate
end
当我点击/projects/1
时,上面的代码会产生:
{
"id": 1,
"name": "123 Park Ave.",
"updated_at": "2015-08-09T02:36:23.950Z",
"estimates": [
{
"id": 1,
"name": "E1",
"release_version": "v1.0",
"exchange_rate": "0.0",
"updated_at": "2015-08-12T04:23:38.183Z",
"project_id": 1,
"project_code_id": 8,
"tax_type_id": 1
}
]
}
然而,我希望它产生的是:
{
"id": 1,
"name": "123 Park Ave.",
"updated_at": "2015-08-09T02:36:23.950Z",
"estimates": [
{
"id": 1,
"name": "E1",
"release_version": "v1.0",
"exchange_rate": "0.0",
"updated_at": "2015-08-12T04:23:38.183Z",
"project": {
"id": 1,
"name": "123 Park Ave."
},
"project_code": {
"id": 8,
"valuation": 30
},
"tax_type": {
"id": 1,
"name": "no-tax"
},
"proposals": [
{
"id": 1,
"name": "P1",
"updated_at": "2015-08-12T04:23:38.183Z"
},
{
"id": 2,
"name": "P2",
"updated_at": "2015-10-12T04:23:38.183Z"
}
]
}
]
}
理想情况下,我还希望能够指定哪些属性、关联和这些关联的属性包含在每个序列化程序中。
我一直在研究AMS的问题,似乎确实有一些关于应该如何处理的问题(或者这种功能是否实际上被支持),但我很难弄清楚当前的状态到底是什么。
建议的解决方案之一是用调用嵌套属性的方法覆盖属性,但这似乎被认为是一种黑客行为,所以如果可能的话,我想避免这种情况。
无论如何,如果您能举例说明如何处理此问题或一般的API建议,我们将不胜感激。
发布于 2015-08-20 08:54:56
所以这可能不是最好的,甚至不是一个好的答案,但这是我需要的工作方式。
虽然在使用带有AMS的json_api
适配器时似乎支持包含嵌套和侧边加载的属性,但我需要支持flat json。此外,这个方法工作得很好,因为每个序列化程序都专门生成我需要的东西,独立于任何其他序列化程序,而不需要在控制器中做任何事情。
注释/替代方法总是受欢迎的。
项目模型
class Project < ActiveRecord::Base
has_many :estimates, autosave: true, dependent: :destroy
end
ProjectsController
def index
@projects = Project.all
render json: @projects
end
ProjectSerializer
class ProjectSerializer < ActiveModel::Serializer
attributes :id,
:name,
:updated_at,
# has_many
:estimates
def estimates
customized_estimates = []
object.estimates.each do |estimate|
# Assign object attributes (returns a hash)
# ===========================================================
custom_estimate = estimate.attributes
# Custom nested and side-loaded attributes
# ===========================================================
# belongs_to
custom_estimate[:project] = estimate.project.slice(:id, :name) # get only :id and :name for the project
custom_estimate[:project_code] = estimate.project_code
custom_estimate[:tax_type] = estimate.tax_type
# has_many w/only specified attributes
custom_estimate[:proposals] = estimate.proposals.collect{|proposal| proposal.slice(:id, :name, :updated_at)}
# ===========================================================
customized_estimates.push(custom_estimate)
end
return customized_estimates
end
end
结果
[
{
"id": 1,
"name": "123 Park Ave.",
"updated_at": "2015-08-09T02:36:23.950Z",
"estimates": [
{
"id": 1,
"name": "E1",
"release_version": "v1.0",
"exchange_rate": "0.0",
"created_at": "2015-08-12T04:23:38.183Z",
"updated_at": "2015-08-12T04:23:38.183Z",
"project": {
"id": 1,
"name": "123 Park Ave."
},
"project_code": {
"id": 8,
"valuation": 30,
"created_at": "2015-08-09T18:02:42.079Z",
"updated_at": "2015-08-09T18:02:42.079Z"
},
"tax_type": {
"id": 1,
"name": "No Tax",
"created_at": "2015-08-09T18:02:42.079Z",
"updated_at": "2015-08-09T18:02:42.079Z"
},
"proposals": [
{
"id": 1,
"name": "P1",
"updated_at": "2015-08-12T04:23:38.183Z"
},
{
"id": 2,
"name": "P2",
"updated_at": "2015-10-12T04:23:38.183Z"
}
]
}
]
}
]
我基本上忽略了在序列化程序中实现任何has_many
或belongs_to
关联的尝试,而只是定制了行为。我使用slice
来选择特定的属性。希望一个更优雅的解决方案会出现。
发布于 2016-07-02 14:37:03
Per commit 1426:https://github.com/rails-api/active_model_serializers/pull/1426 -和相关讨论,您可以看到json
和attributes
序列化的默认嵌套是一个级别。
如果默认情况下需要深度嵌套,可以在active_model_serializer初始值设定项中设置配置属性:
ActiveModelSerializers.config.default_includes = '**'
有关v0.10.6的详细参考,请访问:https://github.com/rails-api/active_model_serializers/blob/v0.10.6/docs/general/adapters.md#include-option
发布于 2015-09-01 04:28:09
如果您使用的是JSONAPI适配器,则可以执行以下操作来呈现嵌套关系:
render json: @project, include: ['estimates', 'estimates.project_code', 'estimates.tax_type', 'estimates.proposals']
您可以从jsonapi文档中阅读更多内容:http://jsonapi.org/format/#fetching-includes
https://stackoverflow.com/questions/32079897
复制相似问题