mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Add pagination links automatically
Pagination links will be included in your response automatically as long as the resource is paginated using Kaminari or WillPaginate and if you are using a JSON-API adapter. The others adapters does not have this feature.
This commit is contained in:
parent
a41d90cce4
commit
2c2f948fa0
@ -118,7 +118,7 @@ If you wish to use a serializer other than the default, you can explicitly pass
|
|||||||
render json: @posts, each_serializer: PostPreviewSerializer
|
render json: @posts, each_serializer: PostPreviewSerializer
|
||||||
|
|
||||||
# Or, you can explicitly provide the collection serializer as well
|
# Or, you can explicitly provide the collection serializer as well
|
||||||
render json: @posts, serializer: PaginatedSerializer, each_serializer: PostPreviewSerializer
|
render json: @posts, serializer: CollectionSerializer, each_serializer: PostPreviewSerializer
|
||||||
```
|
```
|
||||||
|
|
||||||
### Meta
|
### Meta
|
||||||
@ -272,6 +272,11 @@ 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
|
||||||
|
|
||||||
|
Pagination links will be included in your response automatically as long as the resource is paginated using [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate) and if you are using a ```JSON-API``` adapter. The others adapters does not have this feature.
|
||||||
|
|
||||||
|
For more information about it, please see in our docs [How to add pagination links](https://github.com/rails-api/active_model_serializers/blob/master/docs/howto/add_pagination_links.md)
|
||||||
|
|
||||||
## Caching
|
## Caching
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,19 @@
|
|||||||
# How to add pagination links
|
# How to add pagination links
|
||||||
|
|
||||||
If you want pagination links in your response, specify it in the `render`
|
Pagination links will be included in your response automatically as long as the resource is paginated and if you are using a ```JSON-API``` adapter. The others adapters does not have this feature.
|
||||||
|
|
||||||
|
If you want pagination links in your response, use [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate).
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
render json: @posts, pagination: true
|
#kaminari example
|
||||||
|
@posts = Kaminari.paginate_array(Post.all).page(3).per(1)
|
||||||
|
render json: @posts
|
||||||
|
|
||||||
|
#will_paginate example
|
||||||
|
@posts = Post.all.paginate(page: 3, per_page: 1)
|
||||||
|
render json: @posts
|
||||||
```
|
```
|
||||||
|
|
||||||
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 a ```JSON-API``` adapter, the others adapters doesn't have this feature.
|
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
ActiveModel::Serializer.config.adapter = :json_api
|
ActiveModel::Serializer.config.adapter = :json_api
|
||||||
```
|
```
|
||||||
@ -38,3 +42,5 @@ ex:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
AMS relies on either [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate). Please install either dependency by adding one of those to your Gemfile.
|
||||||
|
|||||||
@ -25,9 +25,10 @@ module ActionController
|
|||||||
"Please pass 'adapter: false' or see ActiveSupport::SerializableResource#serialize"
|
"Please pass 'adapter: false' or see ActiveSupport::SerializableResource#serialize"
|
||||||
options[:adapter] = false
|
options[:adapter] = false
|
||||||
end
|
end
|
||||||
if options[:pagination]
|
if resource.respond_to?(:current_page) && resource.respond_to?(:total_pages)
|
||||||
options[:original_url] = original_url
|
options[:pagination] = {}
|
||||||
options[:query_parameters] = query_parameters
|
options[:pagination][:original_url] = original_url
|
||||||
|
options[:pagination][:query_parameters] = query_parameters
|
||||||
end
|
end
|
||||||
ActiveModel::SerializableResource.serialize(resource, options) do |serializable_resource|
|
ActiveModel::SerializableResource.serialize(resource, options) do |serializable_resource|
|
||||||
if serializable_resource.serializer?
|
if serializable_resource.serializer?
|
||||||
|
|||||||
@ -2,7 +2,7 @@ require "set"
|
|||||||
module ActiveModel
|
module ActiveModel
|
||||||
class SerializableResource
|
class SerializableResource
|
||||||
|
|
||||||
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter, :pagination])
|
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter])
|
||||||
|
|
||||||
def initialize(resource, options = {})
|
def initialize(resource, options = {})
|
||||||
@resource = resource
|
@resource = resource
|
||||||
|
|||||||
@ -164,7 +164,7 @@ module ActiveModel
|
|||||||
def add_links(options)
|
def add_links(options)
|
||||||
links = @hash.fetch(:links) { {} }
|
links = @hash.fetch(:links) { {} }
|
||||||
resources = serializer.instance_variable_get(:@resource)
|
resources = serializer.instance_variable_get(:@resource)
|
||||||
@hash[:links] = add_pagination_links(links, resources, options) if @options[:pagination]
|
@hash[:links] = add_pagination_links(links, resources, options) if options[:pagination]
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_pagination_links(links, resources, options)
|
def add_pagination_links(links, resources, options)
|
||||||
|
|||||||
@ -14,7 +14,7 @@ module ActiveModel
|
|||||||
|
|
||||||
def serializable_hash(options = {})
|
def serializable_hash(options = {})
|
||||||
pages_from.each_with_object({}) do |(key, value), hash|
|
pages_from.each_with_object({}) do |(key, value), hash|
|
||||||
query_parameters = options.fetch(:query_parameters) { {} }
|
query_parameters = options[:pagination].fetch(:query_parameters) { {} }
|
||||||
params = query_parameters.merge(page: { number: value, size: collection.size }).to_query
|
params = query_parameters.merge(page: { number: value, size: collection.size }).to_query
|
||||||
|
|
||||||
hash[key] = "#{url(options)}?#{params}"
|
hash[key] = "#{url(options)}?#{params}"
|
||||||
@ -51,7 +51,7 @@ module ActiveModel
|
|||||||
|
|
||||||
def url(options)
|
def url(options)
|
||||||
self_link = options.fetch(:links) {{}}
|
self_link = options.fetch(:links) {{}}
|
||||||
self_link.fetch(:self) {} ? options[:links][:self] : options[:original_url]
|
self_link.fetch(:self) {} ? options[:links][:self] : options[:pagination][:original_url]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -31,19 +31,16 @@ module ActionController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def render_pagination_using_kaminari
|
def render_pagination_using_kaminari
|
||||||
render json: using_kaminari, adapter: :json_api, pagination: true
|
render json: using_kaminari, adapter: :json_api
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_pagination_using_will_paginate
|
def render_pagination_using_will_paginate
|
||||||
render json: using_will_paginate, adapter: :json_api, pagination: true
|
render json: using_will_paginate, adapter: :json_api
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_array_without_pagination_links
|
def render_array_without_pagination_links
|
||||||
render json: using_will_paginate, adapter: :json_api, pagination: false
|
setup
|
||||||
end
|
render json: @array, adapter: :json_api
|
||||||
|
|
||||||
def render_array_omitting_pagination_options
|
|
||||||
render json: using_kaminari, adapter: :json_api
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -104,12 +101,6 @@ module ActionController
|
|||||||
response = JSON.parse(@response.body)
|
response = JSON.parse(@response.body)
|
||||||
refute response.key? 'links'
|
refute response.key? 'links'
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_array_omitting_pagination_options
|
|
||||||
get :render_array_omitting_pagination_options, page: { number: 2, size: 1 }
|
|
||||||
response = JSON.parse(@response.body)
|
|
||||||
refute response.key? 'links'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -27,15 +27,11 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
|
|
||||||
def data
|
def data
|
||||||
{
|
{ data:[
|
||||||
data: [{
|
{ id:"1", type:"profiles", attributes:{name:"Name 1", description:"Description 1" } },
|
||||||
id:"2",
|
{ id:"2", type:"profiles", attributes:{name:"Name 2", description:"Description 2" } },
|
||||||
type:"profiles",
|
{ id:"3", type:"profiles", attributes:{name:"Name 3", description:"Description 3" } }
|
||||||
attributes:{
|
]
|
||||||
name:"Name 2",
|
|
||||||
description:"Description 2"
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -56,42 +52,48 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
|
|
||||||
def expected_response_with_pagination_links
|
def expected_response_with_pagination_links
|
||||||
data.merge links
|
{}.tap do |hash|
|
||||||
|
hash[:data] = [data.values.flatten.second]
|
||||||
|
hash.merge! links
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def expected_response_with_pagination_links_and_additional_params
|
def expected_response_with_pagination_links_and_additional_params
|
||||||
new_links = links[:links].each_with_object({}) {|(key, value), hash| hash[key] = "#{value}&teste=teste" }
|
new_links = links[:links].each_with_object({}) {|(key, value), hash| hash[key] = "#{value}&teste=teste" }
|
||||||
data.merge links: new_links
|
{}.tap do |hash|
|
||||||
|
hash[:data] = [data.values.flatten.second]
|
||||||
|
hash.merge! links: new_links
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_pagination_links_using_kaminari
|
def test_pagination_links_using_kaminari
|
||||||
serializer = ArraySerializer.new(using_kaminari)
|
serializer = ArraySerializer.new(using_kaminari)
|
||||||
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer, pagination: true)
|
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
||||||
|
|
||||||
assert_equal expected_response_with_pagination_links,
|
assert_equal expected_response_with_pagination_links,
|
||||||
adapter.serializable_hash(original_url: "http://example.com")
|
adapter.serializable_hash(pagination: { original_url: "http://example.com" })
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_pagination_links_using_will_paginate
|
def test_pagination_links_using_will_paginate
|
||||||
serializer = ArraySerializer.new(using_will_paginate)
|
serializer = ArraySerializer.new(using_will_paginate)
|
||||||
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer, pagination: true)
|
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
||||||
|
|
||||||
assert_equal expected_response_with_pagination_links,
|
assert_equal expected_response_with_pagination_links,
|
||||||
adapter.serializable_hash(original_url: "http://example.com")
|
adapter.serializable_hash(pagination: { original_url: "http://example.com" })
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_pagination_links_with_additional_params
|
def test_pagination_links_with_additional_params
|
||||||
serializer = ArraySerializer.new(using_will_paginate)
|
serializer = ArraySerializer.new(using_will_paginate)
|
||||||
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer, pagination: true)
|
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
||||||
assert_equal expected_response_with_pagination_links_and_additional_params,
|
assert_equal expected_response_with_pagination_links_and_additional_params,
|
||||||
adapter.serializable_hash(original_url: "http://example.com",
|
adapter.serializable_hash(pagination: { original_url: "http://example.com",
|
||||||
query_parameters: { teste: "teste"})
|
query_parameters: { teste: "teste"}})
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_not_showing_pagination_links
|
def test_not_showing_pagination_links
|
||||||
serializer = ArraySerializer.new(using_will_paginate)
|
serializer = ArraySerializer.new(@array)
|
||||||
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer, pagination: false)
|
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
||||||
|
|
||||||
assert_equal expected_response_without_pagination_links, adapter.serializable_hash
|
assert_equal expected_response_without_pagination_links, adapter.serializable_hash
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user