如何在ActiveModel::Serializer中将二级关联的嵌套哈希上移一级?
在Ruby on Rails中调整ActiveModel::Serializer的嵌套结构
我有如下ActiveRecord关联模型:
关联模型代码
class Driver has_one :car delegate :tires, to: :car end
class Car belongs_to :driver has_many :tires end
class Tire belongs_to :car end
原序列化器实现
使用嵌套的序列化器结构:
class DriverSerializer < ActiveModel::Serializer attributes :id, :name has_one :car class CarSerializer < ActiveModel::Serializer attributes :id has_many :tires class TireSerializer < ActiveModel::Serializer attributes :id end end end
原输出JSON结构
生成的JSON中tires嵌套在car节点下:
{ "id": 1, "name": "Bob", "car": { "id": 1, "tires": [ { "id": 1 }, { "id": 2 } ... ] } }
需求
希望将tires字段上移一级,直接嵌套在driver节点下,且要复用现有定义的序列化器,不想用Ruby的map方法手动实例化序列化器对象。已知可以通过自定义属性方法实现,但想找更简洁的方式。
解决方案
可以直接在DriverSerializer中添加has_many :tires,并指定复用已定义的TireSerializer:
class DriverSerializer < ActiveModel::Serializer attributes :id, :name # 若不需要返回car节点,可删除此行 has_one :car # 直接关联tires,复用嵌套的TireSerializer has_many :tires, serializer: CarSerializer::TireSerializer end
调整后生成的JSON结构:
{ "id": 1, "name": "Bob", "car": { "id": 1 }, "tires": [ { "id": 1 }, { "id": 2 } ... ] }
原理是Driver模型已经通过delegate :tires, to: :car实现了tires方法,ActiveModel::Serializer会自动调用该方法获取数据,配合指定已有的序列化器,无需手动用map处理,完美复用现有代码。
内容的提问来源于stack exchange,提问作者Starscream512
相关产品推荐
相关产品推荐

