# 在Rails中使用 active_model_serializers 构建json response | 大染志
Rails 本身提供很不错的json response功能，可以很方便的将model对象自动转换为json数据。如果我们期望返回的结果很简单也可以构建一个简单的hash,自行编辑你希望的key和value,由Rails 来帮你生成json。那如果是介于两者之间的情况呢？ 我希望将我的model以json的形式返回，但是我并不希望将所有的字段返回。 我希望将我的model中部分属性进行稍微的处理和

大染志

Junv's blog

# 在Rails中使用 active_model_serializers 构建json response

发表于 2015-03-21 更新于 2026-08-04

Rails 本身提供很不错的json response功能，可以很方便的将model对象自动转换为json数据。如果我们期望返回的结果很简单也可以构建一个简单的hash,自行编辑你希望的key和value,由Rails 来帮你生成json。那如果是介于两者之间的情况呢？

- 我希望将我的model以json的形式返回，但是我并不希望将所有的字段返回。
- 我希望将我的model中部分属性进行稍微的处理和计算后返回，这样客户端可以直接使用某些字段，而不需要将应用自身的逻辑暴露给客户端，如我有个model记录微信支付属性，有个字段是关于微信支付（”trade_status”），它的值有trade_success, “wait_for_payment”，显然我们可以返回给客户端 “支付成功”，”等待支付”更好。传统的做法，我们为了达到这个目的，我们不仅需要将trade_stauts进行构建，还需要将其他参数也重复写出来。

ActiveModel::Serializers这个gem 包就可以更好的帮助我们解决上面的痛点，我们只需要对需要返回的属性列举出来，只对需要更改的属性进行计算，其他都不需要了。下面就介绍下它的一些常见用法。

首先安装Gem

    1

    gem 'active_model_serializers'

为了可以在我们的rails 项目中使用它，我们还需要在application controller中添加：

    1

    include ActionController::Serialization

active_model_serializers的使用就是在你是需要返回json的地方，为你的数据创建serializer,你的对象就能通过serializer变成希望的结果。这里假设我有一个User用户对象，User的的大致结构：

    1
    2
    3
    4
    5
    6
    7

    class User
      field :nick_name, type: String
      field :email, type: String
      field :age, type: Integer
      field :password, type:String
      # 等等更多属性。。。
    end

我现在有个UserController,需要以JSON的形式返回用户的基本信息： 昵称，邮箱，是否成年（大于等于18岁算成年），接下来在app 目录下创建serializers 目录，并创建class UserSerializer对象，继承自 ActiveModel::Serializer, 然后我们的serializer就应该是这样：

    1
    2
    3
    4
    5
    6
    7

    class UserSerializer ActiveModel::Serializer
      attributes :nick_name, :email, :if_adult

      def if_adult
        object.age > 18 #object 就是需要被序列化的对象
      end
    end

在serializer中，我们只需要将我们需要的属性通过attributes 的形式列出来，如果model没有的属性，我们需要自行实现该方法。
我们也可以覆盖属性，如上的例子，我们也可以将if_adult 改成age,同样我们需要有：

    1
    2
    3

    def age
      object.age > 18
    end

接下来完成我们的最后一步，在controller中使用serializer

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    class UserController ApplicationController
      def show
        #假设 @user 是我们经过查询后得到的对象
        render json: @user, serializer: UserSerializer
      end

      def index
        #假设 @users 是我们经过查询后得到的对象
        render json: @user, each_serializer: UserSerializer
      end
    end

我们我们希望对一个数组对象进行序列化，我们则需要使用each_serializer，使用该属性后，你的返回结果将变成对象，数组则包裹下对象之下。本例则类似于

    1
    2
    3
    4

    users: [
      {},
      {}
    ]

这里的”users”这是json的根属性， serializer支持用户自定义根属性，

    1

    render json: @user, serializer: UserSerializer, root: 'customer'

我非常喜欢active model serializers 的一个属性是，支持在serializer中访问你希望的属性，在rails 中，很多时候我们希望访问current_user对象，获取当前登录用户的相关信息。那serializer 则可以很好的做的这一点，在active model serializers 中有 serialization_scope 这样一个方法，在application controller 中声明此方法，传入你希望的参数，便可以在serializer class 中自由访问该对象。解决了serializer 与其他对象交互的问题。

    1

    serialization_scope :current_user

在serializer中, scope 对象便是注入的 current_user对象

    1

    scope.email

此外，active model serializers 支持在返回的json中额外注入meta属性，这样既保留了serializer的简单，模板化，也增添了自由度，使得用户可以自行添加一些额外的属性。

更详细的使用还请参考：Github

0%