From 36d21400c9c3b1ffda5846aeb2c9fafdad5d9314 Mon Sep 17 00:00:00 2001 From: Bruno Bacarini Date: Fri, 7 Aug 2015 16:59:44 -0300 Subject: [PATCH] exchange pagination class to inside json_api scope --- README.md | 2 +- lib/active_model/serializer/adapter.rb | 16 ----- .../serializer/adapter/json_api.rb | 17 +++++ .../adapter/json_api/pagination_links.rb | 52 ++++++++++++++++ .../serializer/array_serializer.rb | 5 +- lib/active_model/serializer/pagination.rb | 62 ------------------- lib/active_model_serializers.rb | 1 - test/array_serializer_test.rb | 9 +++ 8 files changed, 81 insertions(+), 83 deletions(-) create mode 100644 lib/active_model/serializer/adapter/json_api/pagination_links.rb delete mode 100644 lib/active_model/serializer/pagination.rb diff --git a/README.md b/README.md index ea5a483c1..86705d1cf 100644 --- a/README.md +++ b/README.md @@ -283,7 +283,7 @@ If you want pagination links in your response, specify it in the `render` AMS relies on either Kaminari or WillPaginate. Please install either dependency by adding one of those to your Gemfile. -Pagination links will only be included in your response if you are using an Adapter that supports `root`, as JsonAPI and Json adapters, the default adapter (FlattenJson) doesn't have `root`. +Pagination links will only be included in your response if you are using a JsonAPI adapter, the others adapters doesn't have this feature. ## Caching diff --git a/lib/active_model/serializer/adapter.rb b/lib/active_model/serializer/adapter.rb index 89ace2464..1d6381287 100644 --- a/lib/active_model/serializer/adapter.rb +++ b/lib/active_model/serializer/adapter.rb @@ -25,7 +25,6 @@ def as_json(options = nil) return hash if self.class == FlattenJson include_meta(hash) - include_pagination_links(hash) if options && options[:pagination] end end @@ -97,21 +96,6 @@ def include_meta(json) json[meta_key] = meta if meta json end - - def include_pagination_links(json) - return unless page_links - - links?(json) ? json.merge!(page_links) : json['links'] = page_links - json - end - - def page_links - @links ||= serializer.page_links - end - - def links?(json) - !json['links'].nil? - end end end end diff --git a/lib/active_model/serializer/adapter/json_api.rb b/lib/active_model/serializer/adapter/json_api.rb index 551ed54b1..30946b0fe 100644 --- a/lib/active_model/serializer/adapter/json_api.rb +++ b/lib/active_model/serializer/adapter/json_api.rb @@ -1,4 +1,5 @@ require 'active_model/serializer/adapter/json_api/fragment_cache' +require 'active_model/serializer/adapter/json_api/pagination_links' module ActiveModel class Serializer @@ -27,6 +28,8 @@ def serializable_hash(options = nil) @hash[:included] |= result[:included] end end + + include_pagination_links if serializer.pagination else @hash[:data] = attributes_for_serializer(serializer, options) add_resource_relationships(@hash[:data], serializer) @@ -157,6 +160,20 @@ def add_resource_relationships(attrs, serializer, options = {}) end end end + + def include_pagination_links + return if page_links.empty? + + links? ? @hash[:links].merge!(page_links) : @hash[:links] = page_links + end + + def page_links + @links ||= JsonApi::PaginationLinks.new(serializer.resource).page_links + end + + def links? + !@hash[:links].nil? + end 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 new file mode 100644 index 000000000..3ebc1c51e --- /dev/null +++ b/lib/active_model/serializer/adapter/json_api/pagination_links.rb @@ -0,0 +1,52 @@ +module ActiveModel + class Serializer + class Adapter + class JsonApi < Adapter + class PaginationLinks + FIRST_PAGE = 1 + + attr_reader :collection + + def initialize(collection) + raise_unless_any_gem_installed + @collection = collection + end + + def page_links + build_links + end + + private + + def build_links + pages_from.each_with_object({}) do |(key, value), hash| + hash[key] = "?page=#{value}&per_page=#{collection.size}" + end + end + + def pages_from + return {} if collection.total_pages == FIRST_PAGE + + {}.tap do |pages| + unless collection.current_page == FIRST_PAGE + pages[:first] = FIRST_PAGE + pages[:prev] = collection.current_page - FIRST_PAGE + end + + unless collection.current_page == collection.total_pages + pages[:next] = collection.current_page + FIRST_PAGE + pages[:last] = collection.total_pages + end + end + end + + def raise_unless_any_gem_installed + return if defined?(WillPaginate) || defined?(Kaminari) + raise "AMS relies on either Kaminari or WillPaginate." + + "Please install either dependency by adding one of those to your Gemfile" + end + end + end + end + end +end diff --git a/lib/active_model/serializer/array_serializer.rb b/lib/active_model/serializer/array_serializer.rb index 7a8d14ac2..8417d9e27 100644 --- a/lib/active_model/serializer/array_serializer.rb +++ b/lib/active_model/serializer/array_serializer.rb @@ -4,9 +4,8 @@ class ArraySerializer NoSerializerError = Class.new(StandardError) include Enumerable delegate :each, to: :@objects - delegate :page_links, to: :pagination - attr_reader :root, :meta, :meta_key, :pagination + attr_reader :root, :meta, :meta_key, :pagination, :resource def initialize(objects, options = {}) @root = options[:root] @@ -25,7 +24,7 @@ def initialize(objects, options = {}) end @meta = options[:meta] @meta_key = options[:meta_key] - @pagination = ActiveModel::Serializer::Pagination.new(objects) if options[:pagination] + @pagination = options[:pagination] end def json_key diff --git a/lib/active_model/serializer/pagination.rb b/lib/active_model/serializer/pagination.rb deleted file mode 100644 index 639eaeedb..000000000 --- a/lib/active_model/serializer/pagination.rb +++ /dev/null @@ -1,62 +0,0 @@ -module ActiveModel - class Serializer - class Pagination - attr_reader :collection - - def initialize(collection) - @collection = collection - end - - def page_links - send(default_adapter) - end - - private - - def kaminari - build_links collection.size - end - - def will_paginate - setup_will_paginate - build_links collection.per_page - end - - def build_links(per_page) - pages_from.each_with_object({}) do |(key, value), hash| - hash[key] = "?page=#{value}&per_page=#{per_page}" - end - end - - def pages_from - return {} if collection.total_pages == 1 - - {}.tap do |pages| - unless collection.first_page? - pages[:first] = 1 - pages[:prev] = collection.current_page - 1 - end - - unless collection.last_page? - pages[:next] = collection.current_page + 1 - pages[:last] = collection.total_pages - end - end - end - - def default_adapter - return :kaminari if defined?(Kaminari) - return :will_paginate if defined?(WillPaginate::CollectionMethods) - raise "AMS relies on either Kaminari or WillPaginate." + - "Please install either dependency by adding one of those to your Gemfile" - end - - def setup_will_paginate - WillPaginate::CollectionMethods.module_eval do - def first_page?() !previous_page end - def last_page?() !next_page end - end - end - end - end -end diff --git a/lib/active_model_serializers.rb b/lib/active_model_serializers.rb index bf5f5d566..211a2870e 100644 --- a/lib/active_model_serializers.rb +++ b/lib/active_model_serializers.rb @@ -2,7 +2,6 @@ require 'active_model/serializer/version' require 'active_model/serializer' require 'active_model/serializer/fieldset' -require 'active_model/serializer/pagination' require 'active_model/serializable_resource' begin diff --git a/test/array_serializer_test.rb b/test/array_serializer_test.rb index 3eff3ef8a..60caf9bc2 100644 --- a/test/array_serializer_test.rb +++ b/test/array_serializer_test.rb @@ -92,6 +92,15 @@ def test_json_key_with_root_and_no_serializers serializer = ArraySerializer.new(build_named_collection, root: 'custom_root') assert_equal serializer.json_key, 'custom_roots' end + + def test_pagination_attr_readers + serializer = ArraySerializer.new(@resource, pagination: true) + assert_equal serializer.pagination, true + end + + def test_resource + assert_equal @serializer.resource, @resource + end end end end