amazon

[Rails] Pagy 5 系で JSON:API形式のページネーションパラメータの定義方法

はじめに

以前遊びで作った API で JSON:API[1] のサンプルに記載されている形式(page[number]=3&page[size]=1)でページネーションパラメータを構築していました。 Pagy[2]3系 を使用して実現していましたが、無謀にも5系に上げた際に躓いたので忘備録として記載します。

作業

実現したい構造

実現したい構造のサンプルを以下に記載します。link 配下の形式の URL を生成したいです。

{
  "data": [
    {・・・略・・・}
  ],
  "links": {
    "prev": "http://example.com/articles?page[number]=2&page[size]=1",
    "next": "http://example.com/articles?page[number]=4&page[size]=1"
  }
}

修正前のコードと Pagy5系で動かした結果を記載します。

class TestController < ApplicationController
  include Pagy::Backend
  require "pagy/extras/metadata"

  def index
    pagy, items = pagy(
      Test.all,
      params: {
        page: {
          number: Pagy::PAGE_PLACEHOLDER,
          size: page[:size]
        }
      }
    )
    render json: TestSerializer.new(items, pagy).serialized_json
  end

  private

  Pagy::VARS[:page_param] = "dummy"

  def build_pagy(resources)
    pagy(
      resources,
      params: {
        page: { number: Pagy::PAGE_PLACEHOLDER, size: page[:size] }
      }
    )
  end

  def pagy_get_params(params)
    params.except(Pagy::VARS[:page_param].to_s)
  end
end

#> links: {
  prev: "http://example.com?page[number]=1&page[size]=20&dummy=__pagy_page__",
  next: ・・・以下同様なので省略・・・
}

末尾に「dummy=__pagy_page__」という文字が付くようになりました。

原因と対応

原因

pagy_get_params というメソッドが rename[3] されたため、Pagy::VARS[:page_parms] の値を除外する処理が効かなくなっていたためです。

対応

pagyでデータ生成時に、以下のように既存部分の変更を加えました。pagy_massage_params というメソッドは v6 で削除されるっぽいんで今後も使える形式の修正を加えます

def index
  pagy, items = pagy(
    Test.all,
    params: proc { |paramater|
      paramater.merge(
        page: { number: Pagy::PAGE_PLACEHOLDER, size: page[:size] }
      ).except(Pagy::DEFAULT[:page_param])
    }
  )
  render json: TestSerializer.new(items, pagy).serialized_json
end

おわりに

メジャーバージョン一気に2つ上げるというヤバイ対応してしまったのが一因ですが、定期的に更新続けるべきでしたね。

参考

[1] JSON:API , https://jsonapi.org/examples/
[2] Pagy, https://github.com/ddnexus/pagy
[3] Pagy: Breaking changes – 2. Simple search and replace, https://github.com/ddnexus/pagy/blob/master/CHANGELOG.md#breaking-changes—2-simple-search-and-replace

コメント

タイトルとURLをコピーしました

Fatal error: Uncaught JSMin_UnterminatedRegExpException: JSMin: Unterminated RegExp at byte 329: /^https?:\/\ in /bitnami/wordpress/wp-content/plugins/autoptimize/classes/external/php/jsmin.php:266 Stack trace: #0 /bitnami/wordpress/wp-content/plugins/autoptimize/classes/external/php/jsmin.php(152): JSMin->action() #1 /bitnami/wordpress/wp-content/plugins/autoptimize/classes/external/php/jsmin.php(86): JSMin->min() #2 /bitnami/wordpress/wp-content/plugins/autoptimize/classes/external/php/ao-minify-html.php(257): JSMin::minify() #3 [internal function]: AO_Minify_HTML->_removeScriptCB() #4 /bitnami/wordpress/wp-content/plugins/autoptimize/classes/external/php/ao-minify-html.php(108): preg_replace_callback() #5 /bitnami/wordpress/wp-content/plugins/autoptimize/classes/external/php/ao-minify-html.php(47): AO_Minify_HTML->process() #6 /bitnami/wordpress/wp-content/plugins/autoptimize/classes/autoptimizeHTML.php(105): AO_Minify_HTML::minify() #7 /bitnami/wordpress/wp-content/plugins/autoptimize/classes/autoptimizeMain.php(592): in /bitnami/wordpress/wp-content/plugins/autoptimize/classes/external/php/jsmin.php on line 266