Techioz Blog

JR gemでリソースごとの最大ページサイズ構成を指定する方法

概要

したがって、jsonapi-resources gemを使用するレールアプリケーションがあり、グローバル構成でこの構成を指定しました

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

https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://jsonapi-resources.com/v0.10/guide/basic_usage.html

ただし、別の API リソース (/api/logs など) でカスタムの minimum_page_size を使用したいと考えています。

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

SO私の質問は、この特定の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 

これで、リソースのページネーターを指定できるようになります。

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

これをより柔軟にする必要がある場合、たとえば、固定定数ではありません。次に、適切な制限を設定してオンザフライで動的にクラスを作成し、それをページネータとして利用するメソッドを作成する必要があります。

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  

注: 私はこのライブラリを使用したことがないため、より良い解決策がある可能性があります。