如何在JSON响应中暴露STI的inheritance_column供Angular前端获取?
如何在JSON响应中暴露STI的type字段给Angular前端
首先得说,你的STI方案完全没问题!因为只有Customer额外多两个字段,单表继承是非常合适的选择,不用纠结方案的问题~
回到你的核心需求:让Angular前端能拿到type字段(也就是STI的inheritance_column)。看了你的代码,问题出在控制器没有使用你定义的UserSerializer来序列化对象,而是直接返回了User实例,导致序列化器里配置的字段没生效。下面给你两种解决办法:
方法一:用你写好的UserSerializer来处理序列化
你已经在UserSerializer里明确加了:type属性,那只要在控制器里调用这个序列化器就行,修改show方法:
def show user = User.find(params[:id]) if user.present? # 用序列化器处理后再返回 render json: { data: UserSerializer.new(user).serializable_hash }, status: 200 else head 404 end end
这样响应里就会包含序列化器中定义的所有字段,包括type了。
方法二:不使用序列化器,直接让ActiveRecord返回type字段
如果你暂时不想用序列化器,也可以通过两种方式确保type被包含在JSON里:
方式A:在render时指定要返回的字段
直接在show方法里用as_json指定字段:
def show user = User.find(params[:id]) if user.present? render json: { data: user.as_json(only: [:id, :name, :email, :type]) }, status: 200 else head 404 end end
方式B:在模型里重写as_json,默认包含type
在user.rb里添加一段代码,让每次序列化User实例时都默认包含需要的字段:
def as_json(options = {}) # 合并默认字段和传入的options super(options.merge(only: [:id, :name, :email, :type])) end
这样以后不管是render json: user还是user.to_json,都会自动带上type字段。
另外补充几点:
- 你的
user_params已经允许了:type参数,这很好,确保创建/更新用户时type能被正确赋值; - STI默认的inheritance_column就是
type,你的模型配置完全正确,不用额外修改; - 没有
config/initializers/active_model_serializer.rb文件完全没关系,新版本的AMS不需要这个初始化文件,直接调用序列化器就行。
内容的提问来源于stack exchange,提问作者rom
相关产品推荐
相关产品推荐

