Ruby Active Model Serializer:自定义序列化器嵌套结构失效问题
解决Active Model Serializer在自定义响应结构中无法触发序列化器的问题
当你把集合嵌套在自定义哈希结构里传给render json:时,Active Model Serializer(AMS)不会自动识别并应用each_serializer,因为AMS只会直接处理传给render json:的顶层对象。下面是几种可行的解决方案:
方案1:手动序列化集合后嵌入哈希
直接用序列化器处理集合,生成序列化后的哈希,再把结果放进自定义结构的data字段中:
def index applications = Application.all serialized_applications = ApplicationIndexSerializer.new(applications).serializable_hash render json: { meta: {}, data: serialized_applications }, status: 200 end
方案2:编写顶层序列化器封装响应结构
创建一个专门的序列化器来包裹整个响应,把meta和data都定义为序列化器的属性,其中data关联到你的集合并指定子序列化器:
首先定义顶层序列化器:
class ApplicationListSerializer < ActiveModel::Serializer attributes :meta has_many :data, serializer: ApplicationIndexSerializer def meta # 这里可以填充实际的元数据,比如分页信息、总数等 {} end def data # 这里把顶层对象(applications集合)作为data字段的数据源 object end end
然后在控制器中使用这个顶层序列化器:
def index applications = Application.all render json: applications, serializer: ApplicationListSerializer, status: 200 end
方案3:使用SerializableResource处理集合(AMS 0.10+)
如果你的AMS版本是0.10及以上,可以用ActiveModelSerializers::SerializableResource来处理集合,再嵌入自定义结构:
def index applications = Application.all serializable_resource = ActiveModelSerializers::SerializableResource.new( applications, each_serializer: ApplicationIndexSerializer ) render json: { meta: {}, data: serializable_resource.serializable_hash }, status: 200 end
为什么原来的写法不生效?
当你直接把applications集合传给render json:时,Rails会和AMS协作,自动识别这是一个集合,并应用each_serializer来逐个序列化元素。但当集合嵌套在哈希的data值中时,AMS只会把整个哈希当作普通对象处理,不会递归处理内部的集合,因此each_serializer参数不会被触发。
内容的提问来源于stack exchange,提问作者haaaaa199
相关产品推荐
相关产品推荐

