活动模型序列化程序:在ArraySerializer的根目录外添加额外信息

GMA*_*GMA 12 ruby ruby-on-rails activemodel active-model-serializers

假设我有一个模型User和一个序列化程序UserSerializer < ActiveModel::Serializer,以及一个如下所示的控制器:

class UsersController < ApplicationController
  respond_to :json
  def index
    respond_with User.all
  end
end
Run Code Online (Sandbox Code Playgroud)

现在,如果我访问,/users我将得到一个如下所示的JSON响应:

{
  "users": [
    {
      "id": 7,
      "name": "George"
    },
    {
      "id": 8,
      "name": "Dave"
    }
    .
    .
    .
  ]
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我想在JSON响应中包含一些与任何特定用户无关的额外信息,该怎么办?例如:

{
  "time": "2014-01-06 16:52 GMT",
  "url": "http://www.example.com", 
  "noOfUsers": 2,
  "users": [
    {
      "id": 7,
      "name": "George"
    },
    {
      "id": 8,
      "name": "Dave"
    }
    .
    .
    .
  ]
}
Run Code Online (Sandbox Code Playgroud)

这个例子是设计的,但它是我想要实现的很好的近似.活动模型序列化器可以实现这一点吗?(也许通过子类化ActiveModel::ArraySerializer?我无法弄明白).如何添加额外的根元素?

小智 10

您可以将它们作为第二个争论传递给respond_with

def index
 respond_with User.all, meta: {time: "2014-01-06 16:52 GMT",url: "http://www.example.com", noOfUsers: 2}
end
Run Code Online (Sandbox Code Playgroud)

在初始化程序集中的0.9.3版中 ActiveModel::Serializer.root = true:

ActiveSupport.on_load(:active_model_serializers) do
  # Disable for all serializers (except ArraySerializer)
  ActiveModel::Serializer.root = true
end
Run Code Online (Sandbox Code Playgroud)

在控制器中

render json: @user,  meta: { total: 10 }
Run Code Online (Sandbox Code Playgroud)


GMA*_*GMA 4

使用以下方法让它工作render

render json: {
  "time": "2014-01-06 16:52 GMT",
  "url": "http://www.example.com", 
  "noOfUsers": 2,
  "users": @users
}
Run Code Online (Sandbox Code Playgroud)

问题是,这不会调用UserSerializer,它只是调用.as_json每个单独的用户对象并跳过序列化器。所以我必须明确地这样做:

def index
  .
  .
  .
  render json: {
    "time": "2014-01-06 16:52 GMT",
    "url": "http://www.example.com", 
    "noOfUsers": 2,
    "users": serialized_users
  }
end

def serialized_users
  ActiveModel::ArraySerializer.new(@users).as_json
end
Run Code Online (Sandbox Code Playgroud)

这不是最优雅的解决方案,但它确实有效。