42

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

/people

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

/people/1

我不知道如何使用 ActiveModel::Serializers 来做到这一点,因为这些示例都使用了为每个模型定义一个序列化器(使用标准命名约定)并让 AMS 在您这样做时自动在控制器中使用正确的序列化器的模式:

render json: @people

或者:

render json: @person
4

4 回答 4

125

可以为同一模型拥有多个序列化程序,例如

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
于 2012-10-25T15:48:36.697 回答
10
class CompletePersonSerializer < ActiveModel::Serializer
  root :person
  attributes :id, :name, :phone, :email
end

或者

render json: @people, each_serializer: CompletePersonSerializer, root: :person
于 2013-06-17T21:33:37.263 回答
4

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

jbuilderrabl都很好地满足了这种数据模板化需求。

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

于 2012-09-27T04:50:58.667 回答
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
于 2013-10-10T20:30:11.537 回答