ruby 如何在JR gem中指定每个资源的maximum_page_size配置

iibxawm4  于 12个月前  发布在  Ruby
关注(0)|答案(1)|浏览(102)

所以我有一个使用jsonapi-resources 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资源指定配置?

5anewei6

5anewei61#

从我在源代码中可以确定的是,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

然后使用as

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

请注意:我没有使用过这个库,所以可能有更好的解决方案。

相关问题