如何使用ActiveModel :: Serializers为同一模型实现多个不同的序列化器?

时间:2012-09-18 21:33:00

标签: ruby-on-rails-3 json rest activemodel

假设您正在Rails中实现REST API。提供集合时,您可能只想包含一些属性:

/people

但是,当提供单个资源时,您希望包含所有属性:

/people/1

我没有看到如何使用ActiveModel :: Serializers,因为这些示例都使用每个模型定义一个序列化程序的模式(使用标准命名约定)并且AMS在控制器中自动使用正确的模式你这样做:

render json: @people

或:

render json: @person

4 个答案:

答案 0 :(得分:108)

可以为同一型号提供多个序列化程序,例如

class SimplePersonSerializer < ActiveModel::Serializer
  attributes :id, :name
end

class CompletePersonSerializer < ActiveModel::Serializer
  attributes :id, :name, :phone, :email
end

一个控制器中的人的简单信息:

render json: @people, each_serializer: SimplePersonSerializer

另一个人的完整信息:

render json: @people, each_serializer: CompletePersonSerializer

单个人的简单信息:

render json: @person, serializer: SimplePersonSerializer

单个人的完整信息:

render json: @person, serializer: CompletePersonSerializer

答案 1 :(得分:10)

class CompletePersonSerializer < ActiveModel::Serializer
  root :person
  attributes :id, :name, :phone, :email
end

render json: @people, each_serializer: CompletePersonSerializer, root: :person

答案 2 :(得分:4)

为避免将视图问题混合到模型中(通过序列化变体),请使用视图为每个操作呈现JSON,就像我们对HTML一样。

jbuilder&amp; rabl两者都很好地填补了这个数据的模板需求。

更新2013-12-16 ActiveModelSerializers库确实支持为一个模型定义多个序列化程序,正如@phaedryx稍后使用custom serializers回答的那样。

答案 3 :(得分:2)

添加@phaedryx所说的,我为此做的是调用一个返回正确序列化器的方法...对于你的问题,我会用:

class MyController < ApplicationController

  def index
    render json: @people, each_serializer: serializer_method
  end

  private

  def serializer_method
    defined?(@people) ? PeopleSerializer : PersonSerializer
  end

end