はじめに
以前遊びで作った 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
コメント