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

odi*_*ity 36 rest json activemodel ruby-on-rails-3

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

/people
Run Code Online (Sandbox Code Playgroud)

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

/people/1
Run Code Online (Sandbox Code Playgroud)

我没有看到如何使用ActiveModel :: Serializers,因为这些示例都使用每个模型定义一个序列化程序的模式(使用标准命名约定),并且当您执行以下操作时AMS会自动使用控制器中的正确模式:

render json: @people
Run Code Online (Sandbox Code Playgroud)

要么:

render json: @person
Run Code Online (Sandbox Code Playgroud)

pha*_*ryx 112

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

class SimplePersonSerializer < ActiveModel::Serializer
  attributes :id, :name
end
Run Code Online (Sandbox Code Playgroud)

class CompletePersonSerializer < ActiveModel::Serializer
  attributes :id, :name, :phone, :email
end
Run Code Online (Sandbox Code Playgroud)

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

render json: @people, each_serializer: SimplePersonSerializer
Run Code Online (Sandbox Code Playgroud)

另一个人的完整信息:

render json: @people, each_serializer: CompletePersonSerializer
Run Code Online (Sandbox Code Playgroud)

单个人的简单信息:

render json: @person, serializer: SimplePersonSerializer
Run Code Online (Sandbox Code Playgroud)

一个人的完整信息:

render json: @person, serializer: CompletePersonSerializer
Run Code Online (Sandbox Code Playgroud)

  • @chopper是的.你只需要追加`root :: person`.这是一个完整的例子`render json:@person,serializer:CompletePersonSerializer,root :: person` (9认同)
  • 您可以继承`class CompletePersonSerializer <SimplePersonSerializer`并仅包含新属性 (3认同)
  • @SeifSallam你可以将`root:person`添加到它自己的序列化器类中.不需要在任何地方指定`render json` (3认同)
  • 我怎样才能把键作为`person:{}`而不是`complete_person:{}`? (2认同)
  • @SeifSallam,你有没有想过这个?我有同样的问题 (2认同)
  • Phaedryx和@Swards你们是我的英雄! (2认同)

小智 10

class CompletePersonSerializer < ActiveModel::Serializer
  root :person
  attributes :id, :name, :phone, :email
end
Run Code Online (Sandbox Code Playgroud)

要么

render json: @people, each_serializer: CompletePersonSerializer, root: :person
Run Code Online (Sandbox Code Playgroud)


Mar*_*ars 4

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

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

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

  • 那么,您的意思是,AMS 目前的设计尚不具备灵活性,无法满足针对不同 API 响应进行不同序列化的常见用例?因为这就是感觉,但我不想假设问题不仅仅是我自己的无知,特别是因为 AMS 被认为是 Rails4 核心的“方式”...... (2认同)