add feature to include pagination links in response

This commit is contained in:
Bruno Bacarini 2015-08-02 18:02:56 -03:00
parent e384b65f5d
commit f7c77c1256
6 changed files with 98 additions and 4 deletions

1
.gitignore vendored
View File

@ -19,3 +19,4 @@ test/version_tmp
tmp tmp
*.swp *.swp
.ruby-version .ruby-version
.ruby-gemset

View File

@ -273,6 +273,18 @@ And you can change the JSON key that the serializer should use for a particular
The `url` declaration describes which named routes to use while generating URLs The `url` declaration describes which named routes to use while generating URLs
for your JSON. Not every adapter will require URLs. for your JSON. Not every adapter will require URLs.
## Pagination
If you want pagination links in your response, specify it in the `render`
```ruby
render json: @posts, pagination: true
```
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`.
## Caching ## Caching
To cache a serializer, call ```cache``` and pass its options. To cache a serializer, call ```cache``` and pass its options.

View File

@ -21,9 +21,9 @@ module ActiveModel
end end
def as_json(options = nil) def as_json(options = nil)
hash = serializable_hash(options) serializable_hash(options).tap do |hash|
include_meta(hash) include_meta(hash)
hash end
end end
def self.create(resource, options = {}) def self.create(resource, options = {})
@ -94,6 +94,21 @@ module ActiveModel
json[meta_key] = meta if meta json[meta_key] = meta if meta
json json
end 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 end
end end

View File

@ -4,8 +4,9 @@ module ActiveModel
NoSerializerError = Class.new(StandardError) NoSerializerError = Class.new(StandardError)
include Enumerable include Enumerable
delegate :each, to: :@objects delegate :each, to: :@objects
delegate :page_links, to: :pagination
attr_reader :root, :meta, :meta_key attr_reader :root, :meta, :meta_key, :pagination
def initialize(objects, options = {}) def initialize(objects, options = {})
@root = options[:root] @root = options[:root]
@ -24,6 +25,7 @@ module ActiveModel
end end
@meta = options[:meta] @meta = options[:meta]
@meta_key = options[:meta_key] @meta_key = options[:meta_key]
@pagination = ActiveModel::Serializer::Pagination.new(objects) if options[:pagination]
end end
def json_key def json_key

View File

@ -0,0 +1,63 @@
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 = pages_from.each_with_object({}) do |(key, value), hash|
hash[key] = "?page=#{value}&per_page=#{per_page}"
end
{ pages: pages } unless pages.empty?
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

View File

@ -2,6 +2,7 @@ require 'active_model'
require 'active_model/serializer/version' require 'active_model/serializer/version'
require 'active_model/serializer' require 'active_model/serializer'
require 'active_model/serializer/fieldset' require 'active_model/serializer/fieldset'
require 'active_model/serializer/pagination'
require 'active_model/serializable_resource' require 'active_model/serializable_resource'
begin begin