【问题标题】:Rails Grape API pagination with AMS and custom JSON使用 AMS 和自定义 JSON 的 Rails Grape API 分页
【发布时间】:2016-06-07 13:51:16
【问题描述】:

在 Rails 中做可能需要更复杂/更有创意的解决方案,但基本上使用 Grape、active_model_serializers (AMS) 和 grape-kaminari 来返回用户对象的索引路由(列表),我希望能够使用 AMS 的缓存和轻松序列化对象的优势,但自定义 JSON 响应。

这是葡萄:

module API
  module V1
    class Users < Grape::API
      include API::V1::Defaults
      include Grape::Kaminari

      resource :users do
         paginate per_page: 18
         get do
           users = User.all
           paginate users
         end
      end
    end
  end
end

和 AMS:

class UserSerializer < ActiveModel::Serializer
  cache key: 'user', expires_in: 3.hours
  attributes :id, :firstname, :lastname, :email, :username
end

JSON 中的理想响应:

{
  users: [
    {
      id: 1,
      firstname: "Daniel",
      lastname: "Archer,
      email: "daniel@archer.co",
      username: "dja"
     },
    {
      id: 2,
      firstname: "Fakey",
      lastname: "McFakerson,
      email: "fake@fake.io",
      username: "fake"
     }
  ],
  extras: {
    user_count: 300,
    new_users_last_5_days: 10,
    new_users_last_30_days: 25
  }
}

我希望(并且遇到问题)是在 JSON 响应中对用户数量进行分页,但包括一些与整个用户集合相关的额外内容。例如,我可能有 300 个用户,但我只想返回前 18 个用户(或者基于参数 per_pagepage 的更多用户),以及整个集合的额外数据。

【问题讨论】:

    标签: ruby-on-rails pagination kaminari active-model-serializers ruby-grape


    【解决方案1】:

    使用 Grape::Entity,您可以呈现多个值。

    paginate users
    

    只显示选定的用户页面。您可以在此之后添加另一个 present

    present :extras, {user_count: User.count, ...}
    

    回答您的评论:
    我正在使用类似的设置,并有一个用 kaminary 分页并用额外数据扩展的响应:

    get do
      ...
      present :statistics, statistics, with: API::Entities::Statistics
      present :refresh_time, Setting.list_refresh_time
      present :users, @users.page(params[:page]).per(18), with: API::Entities::User
    end
    

    使用 vanilla Grape,返回一个数据结构,该结构根据输出格式进行转换,即使用.to_json。所以你可以返回一个哈希:

    get do
      ...
      { statistics: some_statistics, 
        users: @users.page(params[:page]).per(18)
      }
    end
    

    【讨论】:

    • 所以你的意思是在paginate users之后的一行添加present :extras, {user_count: User.count, ...}?这似乎对我不起作用..
    • 或者这需要使用葡萄实体吗?
    • 我在有和没有葡萄实体的情况下使用它。
    • 当我使用present时,我只会得到最后一个presenter.. :/
    • 承认,presentGrape::Entity 的工具。 Vanilla Grape 返回单个数据结构,我扩展了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 2017-01-22
    • 1970-01-01
    • 2014-07-04
    相关资源
    最近更新 更多