Edited at

カーソルでページネーションする activerecord-cursor 作った


はじめに

カーソルでページネーションするという要件があり、いい感じのGemを探したが存在しなかったので自作した


既存のGem

があった。 cursorはkeyがidにしか対応していなかったので使えなかった。cursor_paginationは実は実装後に発見したのだが、5年間メンテされてないっぽいのと、カーソルを生成するのにクエリを発行しているので、まぁ作ってよかったと思う

cursor_paginationは自分のよりも機能が豊富なので、検討してみても良いと思う


activerecord-cursor

tsuwatch/activerecord-cursor


使い方

Post.cursor(key: :created_at)

=> [#<Post id: 1, published: false, created_at: "2018-12-30 19:38:27", updated_at: "2018-12-30 19:38:27">]
Post.cursor(key: :created_at, start: Post.next_cursor)
=> [#<Post id: 2, published: false, created_at: "2018-12-30 19:38:28", updated_at: "2018-12-30 19:38:28">]


オプション


  • key


    • ソートするカラムを指定(デフォルトはid)



  • reverse


    • ソート順が昇順か降順かを指定(デフォルトは昇順)



  • size


    • 1ページあたりの取得件数(デフォルトは1件)



  • start


    • カーソルを指定。指定したカーソル以降のレコードを取得



  • stop


    • カーソルを指定。指定したカーソルより前のレコードを取得




カーソルについて

ページネーションを実現するため、前後ページのカーソルを取得できる

Post.next_cursor # 次のページ用カーソル

Post.prev_cursor # 前のページ用カーソル

取得できる値は、内部的にレコードを取得するために必要な値(Hash)をto_yamlし、Base64.urlsafe_encodeしたものになっていて、クエリストリングとして利用可能になっている。この値をstartもしくはstopに渡すことで使用する

また、1回のクエリ発行でカーソルを特定することを実現している。そのため、内部的には指定されたsizeから余分に+1して取得してそこから削るというような実装になっている


さいごに

今後は、configファイルの生成やヘルパーなど気が向いたら実装していきます

ぜひ採用の検討をいただければと思います