From 7be25fef14f04054a8728acee3dae2086c621e0e Mon Sep 17 00:00:00 2001 From: Bruno Bacarini Date: Mon, 10 Aug 2015 12:26:16 -0300 Subject: [PATCH] include query_parameters on pagination links as well --- docs/howto/add_pagination_links.md | 8 ++-- lib/action_controller/serialization.rb | 9 +++- .../adapter/json_api/pagination_links.rb | 15 +++---- .../json_api/pagination_test.rb | 35 ++++++++++------ test/action_controller/serialization_test.rb | 6 --- .../adapter/json_api/pagination_links_test.rb | 42 ++++++++++++------- 6 files changed, 71 insertions(+), 44 deletions(-) diff --git a/docs/howto/add_pagination_links.md b/docs/howto/add_pagination_links.md index 960723c4..971e3ee8 100644 --- a/docs/howto/add_pagination_links.md +++ b/docs/howto/add_pagination_links.md @@ -30,10 +30,10 @@ ex: } ], "links": { - "first": "http://example.com/articles?page=1&per_page=1", - "prev": "http://example.com/articles?page=2&per_page=1", - "next": "http://example.com/articles?page=4&per_page=1", - "last": "http://example.com/articles?page=13&per_page=1" + "first": "http://example.com/articles?page[number]=1&page[size]=1", + "prev": "http://example.com/articles?page[number]=2&page[size]=1", + "next": "http://example.com/articles?page[number]=4&page[size]=1", + "last": "http://example.com/articles?page[number]=13&page[size]=1" } } ``` diff --git a/lib/action_controller/serialization.rb b/lib/action_controller/serialization.rb index b3b84322..21aaad48 100644 --- a/lib/action_controller/serialization.rb +++ b/lib/action_controller/serialization.rb @@ -25,7 +25,10 @@ module ActionController "Please pass 'adapter: false' or see ActiveSupport::SerializableResource#serialize" options[:adapter] = false end - options[:original_url] = original_url + if options[:pagination] + options[:original_url] = original_url + options[:query_parameters] = query_parameters + end ActiveModel::SerializableResource.serialize(resource, options) do |serializable_resource| if serializable_resource.serializer? serializable_resource.serialization_scope ||= serialization_scope @@ -62,5 +65,9 @@ module ActionController def original_url request.original_url.sub(/\?.*$/, "") end + + def query_parameters + request.query_parameters + end end end diff --git a/lib/active_model/serializer/adapter/json_api/pagination_links.rb b/lib/active_model/serializer/adapter/json_api/pagination_links.rb index dd4c90c1..bbae19ea 100644 --- a/lib/active_model/serializer/adapter/json_api/pagination_links.rb +++ b/lib/active_model/serializer/adapter/json_api/pagination_links.rb @@ -14,17 +14,14 @@ module ActiveModel end def page_links - build_links + pages_from.each_with_object({}) do |(key, value), hash| + params = query_parameters.merge(page: { number: value, size: collection.size }).to_query + hash[key] = "#{url}?#{params}" + end end private - def build_links - pages_from.each_with_object({}) do |(key, value), hash| - hash[key] = "#{url}?page=#{value}&per_page=#{collection.size}" - end - end - def pages_from return {} if collection.total_pages == FIRST_PAGE @@ -55,6 +52,10 @@ module ActiveModel def default_url options[:original_url] end + + def query_parameters + options[:query_parameters] ? options[:query_parameters] : {} + end end end end diff --git a/test/action_controller/json_api/pagination_test.rb b/test/action_controller/json_api/pagination_test.rb index c8a3647d..41d3ed6f 100644 --- a/test/action_controller/json_api/pagination_test.rb +++ b/test/action_controller/json_api/pagination_test.rb @@ -8,6 +8,9 @@ module ActionController module Serialization class JsonApi class PaginationTest < ActionController::TestCase + KAMINARI_URI = 'http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_kaminari' + WILL_PAGINATE_URI = 'http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_will_paginate' + class PaginationTestController < ActionController::Base def setup @array = [ @@ -47,10 +50,10 @@ module ActionController tests PaginationTestController def test_render_pagination_links_with_will_paginate - expected_links = {"first"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_will_paginate?page=1&per_page=1", - "prev"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_will_paginate?page=1&per_page=1", - "next"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_will_paginate?page=3&per_page=1", - "last"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_will_paginate?page=3&per_page=1"} + expected_links = {"first"=>"#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1&per_page=1", + "prev"=>"#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1&per_page=1", + "next"=>"#{WILL_PAGINATE_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1&per_page=1", + "last"=>"#{WILL_PAGINATE_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1&per_page=1"} get :render_pagination_using_will_paginate, page: 2, per_page: 1 response = JSON.parse(@response.body) @@ -58,31 +61,39 @@ module ActionController end def test_render_only_last_and_next_pagination_links - expected_links = {"next"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_will_paginate?page=2&per_page=2", - "last"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_will_paginate?page=2&per_page=2"} + expected_links = {"next"=>"#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2&per_page=2", + "last"=>"#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2&per_page=2"} get :render_pagination_using_will_paginate, page: 1, per_page: 2 response = JSON.parse(@response.body) assert_equal expected_links, response['links'] end def test_render_pagination_links_with_kaminari - expected_links = {"first"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_kaminari?page=1&per_page=1", - "prev"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_kaminari?page=1&per_page=1", - "next"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_kaminari?page=3&per_page=1", - "last"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_kaminari?page=3&per_page=1"} + expected_links = {"first"=>"#{KAMINARI_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1&per_page=1", + "prev"=>"#{KAMINARI_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1&per_page=1", + "next"=>"#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1&per_page=1", + "last"=>"#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1&per_page=1"} get :render_pagination_using_kaminari, page: 2, per_page: 1 response = JSON.parse(@response.body) assert_equal expected_links, response['links'] end def test_render_only_prev_and_first_pagination_links - expected_links = {"first"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_kaminari?page=1&per_page=1", - "prev"=>"http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_kaminari?page=2&per_page=1"} + expected_links = {"first"=>"#{KAMINARI_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1&per_page=1", + "prev"=>"#{KAMINARI_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=1&per_page=1"} get :render_pagination_using_kaminari, page: 3, per_page: 1 response = JSON.parse(@response.body) assert_equal expected_links, response['links'] end + def test_render_only_last_and_next_pagination_links_with_additional_params + expected_links = {"next"=>"#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2&per_page=2&teste=additional", + "last"=>"#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2&per_page=2&teste=additional"} + get :render_pagination_using_will_paginate, page: 1, per_page: 2, teste: "additional" + response = JSON.parse(@response.body) + assert_equal expected_links, response['links'] + end + def test_array_without_pagination_links get :render_array_without_pagination_links response = JSON.parse(@response.body) diff --git a/test/action_controller/serialization_test.rb b/test/action_controller/serialization_test.rb index d60cdf55..8c89ceac 100644 --- a/test/action_controller/serialization_test.rb +++ b/test/action_controller/serialization_test.rb @@ -404,9 +404,6 @@ module ActionController def use_adapter? false end - def original_url - "http://example.com/" - end }.new assert_match /adapter: false/, (capture(:stderr) { controller.get_serializer(Profile.new) @@ -418,9 +415,6 @@ module ActionController def use_adapter? true end - def original_url - "http://example.com/" - end }.new assert_equal "", (capture(:stderr) { controller.get_serializer(Profile.new) diff --git a/test/adapter/json_api/pagination_links_test.rb b/test/adapter/json_api/pagination_links_test.rb index 7c26c192..1ccfd8a6 100644 --- a/test/adapter/json_api/pagination_links_test.rb +++ b/test/adapter/json_api/pagination_links_test.rb @@ -26,7 +26,7 @@ module ActiveModel @array.paginate(page: 2, per_page: 1) end - def expected_response_without_pagination_links + def data { data: [{ id:"2", @@ -39,25 +39,30 @@ module ActiveModel } end - def expected_response_with_pagination_links + def links { - data: [{ - id:"2", - type:"profiles", - attributes:{ - name:"Name 2", - description:"Description 2" - } - }], links:{ - first: "http://example.com?page=1&per_page=1", - prev: "http://example.com?page=1&per_page=1", - next: "http://example.com?page=3&per_page=1", - last: "http://example.com?page=3&per_page=1" + first: "http://example.com?page%5Bnumber%5D=1&page%5Bsize%5D=1", + prev: "http://example.com?page%5Bnumber%5D=1&page%5Bsize%5D=1", + next: "http://example.com?page%5Bnumber%5D=3&page%5Bsize%5D=1", + last: "http://example.com?page%5Bnumber%5D=3&page%5Bsize%5D=1" } } end + def expected_response_without_pagination_links + data + end + + def expected_response_with_pagination_links + data.merge links + end + + def expected_response_with_pagination_links_and_additional_params + new_links = links[:links].each_with_object({}) {|(key, value), hash| hash[key] = "#{value}&teste=teste" } + data.merge links: new_links + end + def test_pagination_links_using_kaminari serializer = ArraySerializer.new(using_kaminari, pagination: true, original_url: "http://example.com") adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer) @@ -72,6 +77,15 @@ module ActiveModel assert_equal expected_response_with_pagination_links, adapter.serializable_hash end + def test_pagination_links_with_additional_params + serializer = ArraySerializer.new(using_will_paginate, pagination: true, + original_url: "http://example.com", + query_parameters: { teste: "teste"}) + adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer) + + assert_equal expected_response_with_pagination_links_and_additional_params, adapter.serializable_hash + end + def test_not_showing_pagination_links serializer = ArraySerializer.new(using_will_paginate, pagination: false) adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)