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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12485404/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 18:32:32  来源:igfitidea点击:

How to implement multiple different serializers for same model using ActiveModel::Serializers?

ruby-on-rails-3jsonrestactivemodel

提问by odigity

Let's say you're implementing a REST API in Rails. When serving a collection, you might want to only include a few attributes:

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

/people

But when serving a single resource, you want to include all the attributes:

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

/people/1

I don't see how to do that using ActiveModel::Serializers, since the examples all use the pattern of defining one serializer per model (with a standard naming convention) and having AMS automatically use the right one in the controller when you do:

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

render json: @people

or:

或者:

render json: @person

采纳答案by Mars

To avoid mixing view concerns into your models (via serialized variations), use the view to render your JSON for each action, much like we do for HTML.

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

jbuilder& rablboth fill this data templating need quite nicely.

jbuilderrabl都很好地填充了这个数据模板需求。

Update 2013-12-16: The ActiveModelSerializerslibrary does support defining multiple serializers for one model, as @phaedryx answered later, by using custom serializers.

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

回答by phaedryx

You canhave multiple serializers for the same model, e.g.

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

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

and

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

simple info for people in one controller:

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

render json: @people, each_serializer: SimplePersonSerializer

complete info for people in another:

另一个人的完整信息:

render json: @people, each_serializer: CompletePersonSerializer

simple info for a single person:

一个人的简单信息:

render json: @person, serializer: SimplePersonSerializer

complete info for a single person:

一个人的完整信息:

render json: @person, serializer: CompletePersonSerializer

回答by Alexey Pismenskiy

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

or

或者

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

回答by tehprofessor

Adding to what @phaedryx said, what I do for this is call a method that returns the correct serializer... for your question, I'd use:

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

class MyController < ApplicationController

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

  private

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

end