From 13d7cd43036e5090ff051d89652a9fe8ec317dd7 Mon Sep 17 00:00:00 2001 From: Alp Keser Date: Tue, 17 Feb 2026 10:37:23 +0300 Subject: [PATCH] Paginate boards JSON --- app/controllers/boards_controller.rb | 4 ++-- app/views/boards/index.json.jbuilder | 2 +- test/controllers/boards_controller_test.rb | 28 ++++++++++++++++------ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index 1175c889b..a8284b309 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -6,8 +6,8 @@ class BoardsController < ApplicationController def index if request.format.json? - @boards = Current.user.boards.ordered_by_recently_accessed - fresh_when @boards + set_page_and_extract_portion_from Current.user.boards.ordered_by_recently_accessed + fresh_when etag: @page.records else set_page_and_extract_portion_from Current.user.boards end diff --git a/app/views/boards/index.json.jbuilder b/app/views/boards/index.json.jbuilder index 4c8325d73..047401cff 100644 --- a/app/views/boards/index.json.jbuilder +++ b/app/views/boards/index.json.jbuilder @@ -1 +1 @@ -json.array!(@boards, partial: "boards/board", as: :board) +json.array! @page.records, partial: "boards/board", as: :board diff --git a/test/controllers/boards_controller_test.rb b/test/controllers/boards_controller_test.rb index 4b5744f83..8a426f00e 100644 --- a/test/controllers/boards_controller_test.rb +++ b/test/controllers/boards_controller_test.rb @@ -207,7 +207,7 @@ class BoardsControllerTest < ActionDispatch::IntegrationTest assert_equal users(:kevin).boards.count, @response.parsed_body.count end - test "index as JSON includes all boards ordered by recently accessed" do + test "index as JSON paginates and preserves recently-accessed order" do account = accounts("37s") kevin = users(:kevin) baseline_accessed_at = 3.days.ago.change(usec: 0) @@ -216,7 +216,7 @@ class BoardsControllerTest < ActionDispatch::IntegrationTest access.update!(accessed_at: baseline_accessed_at + index.seconds) end - 35.times do |index| + 200.times do |index| board = Board.create!( name: "Recent board #{index}", creator: kevin, @@ -226,14 +226,22 @@ class BoardsControllerTest < ActionDispatch::IntegrationTest board.access_for(kevin).update!(accessed_at: baseline_accessed_at + (index + 1).minutes) end - get boards_path, as: :json - - assert_response :success - expected_ids = kevin.boards.ordered_by_recently_accessed.pluck(:id) - actual_ids = @response.parsed_body.map { |board| board["id"] } + actual_ids = [] + next_page = boards_path(format: :json) + page_count = 0 + + while next_page + get next_page, as: :json + assert_response :success + + page_count += 1 + actual_ids.concat(@response.parsed_body.map { |board| board["id"] }) + next_page = next_page_from_link_header(@response.headers["Link"]) + end assert_equal expected_ids, actual_ids + assert_operator page_count, :>, 1 end test "show as JSON" do @@ -269,4 +277,10 @@ class BoardsControllerTest < ActionDispatch::IntegrationTest assert_response :no_content end + + private + def next_page_from_link_header(link_header) + url = link_header&.match(/<([^>]+)>;\s*rel="next"/)&.captures&.first + URI.parse(url).request_uri if url + end end