因此,我有一个使用jsonapi-resource gem并在全局配置中指定了此配置Rails应用程序

JSONAPI.configure do |config|
  config.maximum_page_size = 1000
end

https://jsonapi-resources.com/v0.10/guide/basic_usage.html

但是我想在不同的API资源中使用定制的MAXIMUM_PAGE_SIZE,例如/api/logs

module Api
  class LogResource < ApplicationResource
    immutable
    model_name 'Api::Log'
    primary_key :uuid

    def self.default_sort
      [{ field: 'time_start', direction: :desc }]
    end
  end
end

那么我的问题是如何只为这个特定的JSON API资源指定配置?

推荐答案

从我在源代码中可以确定的是,maximum_page_size不能在资源级别被直接覆盖,所以处理这个问题的最好方法似乎是实现一个自定义Paginator.

对于您给出的例子,我认为下面这样简单的东西应该可以用:

class LimitedPageSizePaginator < PagedPaginator 
  MAX_PAGE_SIZE = 100 
  def initialize(params) 
    super
    verify_page_size_limit
  end 

  private 
    def verify_page_size_limit
      if @size > MAX_PAGE_SIZE
        fail JSONAPI::Exceptions::InvalidPageValue.new(:size, @size,
                detail: "size exceeds maximum page size of #{MAX_PAGE_SIZE}.")
      end
    end 
end 

然后,您应该能够为您的资源指定Paginator

module Api
  class LogResource < ApplicationResource
    immutable
    model_name 'Api::Log'
    primary_key :uuid
   
    paginator :limited_page_size
    
    def self.default_sort
      [{ field: 'time_start', direction: :desc }]
    end
  end
end

如果您需要使其更灵活,例如,不是固定常量.然后,我们需要创建一个方法,该方法动态地创建一个设置了适当限制的类,然后将其用作Paginator,类似于.

module PaginatorCreator 
  class LimitedPaginator < PagedPaginator 
    class << self 
      attr_accessor :limit
      def paginator_name
        self.name.demodulize.underscore[..-11].to_sym
      end 
    end 

    def initialize(params) 
      super
      verify_page_size_limit
    end 

    private 
      def verify_page_size_limit
        if @size > self.class.limit
          fail JSONAPI::Exceptions::InvalidPageValue.new(:size, @size,
                  detail: "size exceeds maximum page size of #{self.class.limit}.")
        end
      end 
  end

  def self.create_limited_paginator(resource:,limit:) 
    klass = Object.const_set("#{resource.name.demodulize}LimitedPaginator",Class.new(LimitedPaginator)) 
    klass.limit = limit
    resource.paginator(klass.paginator_name)
  end 
end 

然后将其用作

class LogResource < ApplicationResource
    PaginatorCreator.create_limited_paginator(resource: self, limit: 100)
end  

Please Note:我没有使用过此库,因此可能有更好的解决方案.

Ruby-on-rails相关问答推荐

Rails 7通过引擎将方法自动加载到控制器中的方法

为Rails服务器推荐的交付类型

ActiveRecord::声明在类别中无效#new

Ruby on Rails form_with 不显示错误,卡在服务器端

比较 Rails 中的日期

Rails 3 应用程序的 MySQL 集群 (NDB) 与 MySQL 复制 (InnoDB):优点/缺点?

在 JS 模块中使用 Rails-UJS(带有 webpacker 的 Rails 6)

Rails 中页面视图的简单计数器

搭建脚手架时建立关系

如何在特定时区(最好是我的应用程序的默认时区,而不是 UTC)中创建新的 DateTime 对象?

Rails:仅在创建时验证,或者当字段不为空时在更新时验证

在 Rails 中复制模型实例

使用 rvm 更新 ruby​​ 版本后收到警告消息Path set to RVM

如何将 ActionMailer default_url_options 的 :host 动态设置为请求的主机名?

如何在 Ruby 中搜索数组?

我应该在 Heroku Cedar 上使用薄的还是独角兽

Ruby 1.87 与 1.92 Date.parse

Ruby 1.9.2 和 Rails 3 无法打开 rails 控制台

ActionMailer 在开发 Rails 4 中不发送邮件

使用 Rspec 测试关联的正确方法?