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
*.swp
.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
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
To cache a serializer, call ```cache``` and pass its options.

View File

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

View File

@ -4,8 +4,9 @@ module ActiveModel
NoSerializerError = Class.new(StandardError)
include Enumerable
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 = {})
@root = options[:root]
@ -24,6 +25,7 @@ module ActiveModel
end
@meta = options[:meta]
@meta_key = options[:meta_key]
@pagination = ActiveModel::Serializer::Pagination.new(objects) if options[:pagination]
end
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'
require 'active_model/serializer/fieldset'
require 'active_model/serializer/pagination'
require 'active_model/serializable_resource'
begin