Skip to content

Commit 2c2f948

Browse files
committed
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.
1 parent a41d90c commit 2c2f948

File tree

8 files changed

+52
-47
lines changed

8 files changed

+52
-47
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ If you wish to use a serializer other than the default, you can explicitly pass
118118
render json: @posts, each_serializer: PostPreviewSerializer
119119

120120
# Or, you can explicitly provide the collection serializer as well
121-
render json: @posts, serializer: PaginatedSerializer, each_serializer: PostPreviewSerializer
121+
render json: @posts, serializer: CollectionSerializer, each_serializer: PostPreviewSerializer
122122
```
123123

124124
### Meta
@@ -272,6 +272,11 @@ And you can change the JSON key that the serializer should use for a particular
272272

273273
The `url` declaration describes which named routes to use while generating URLs
274274
for your JSON. Not every adapter will require URLs.
275+
## Pagination
276+
277+
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.
278+
279+
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)
275280

276281
## Caching
277282

docs/howto/add_pagination_links.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
# How to add pagination links
22

3-
If you want pagination links in your response, specify it in the `render`
3+
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.
44

5-
```ruby
6-
render json: @posts, pagination: true
7-
```
5+
If you want pagination links in your response, use [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate).
86

9-
AMS relies on either `Kaminari` or `WillPaginate`. Please install either dependency by adding one of those to your Gemfile.
7+
```ruby
8+
#kaminari example
9+
@posts = Kaminari.paginate_array(Post.all).page(3).per(1)
10+
render json: @posts
1011

11-
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.
12+
#will_paginate example
13+
@posts = Post.all.paginate(page: 3, per_page: 1)
14+
render json: @posts
15+
```
1216

1317
```ruby
1418
ActiveModel::Serializer.config.adapter = :json_api
@@ -38,3 +42,5 @@ ex:
3842
}
3943
}
4044
```
45+
46+
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.

lib/action_controller/serialization.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ def get_serializer(resource, options = {})
2525
"Please pass 'adapter: false' or see ActiveSupport::SerializableResource#serialize"
2626
options[:adapter] = false
2727
end
28-
if options[:pagination]
29-
options[:original_url] = original_url
30-
options[:query_parameters] = query_parameters
28+
if resource.respond_to?(:current_page) && resource.respond_to?(:total_pages)
29+
options[:pagination] = {}
30+
options[:pagination][:original_url] = original_url
31+
options[:pagination][:query_parameters] = query_parameters
3132
end
3233
ActiveModel::SerializableResource.serialize(resource, options) do |serializable_resource|
3334
if serializable_resource.serializer?

lib/active_model/serializable_resource.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
module ActiveModel
33
class SerializableResource
44

5-
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter, :pagination])
5+
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter])
66

77
def initialize(resource, options = {})
88
@resource = resource

lib/active_model/serializer/adapter/json_api.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def add_resource_relationships(attrs, serializer, options = {})
164164
def add_links(options)
165165
links = @hash.fetch(:links) { {} }
166166
resources = serializer.instance_variable_get(:@resource)
167-
@hash[:links] = add_pagination_links(links, resources, options) if @options[:pagination]
167+
@hash[:links] = add_pagination_links(links, resources, options) if options[:pagination]
168168
end
169169

170170
def add_pagination_links(links, resources, options)

lib/active_model/serializer/adapter/json_api/pagination_links.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def initialize(collection)
1414

1515
def serializable_hash(options = {})
1616
pages_from.each_with_object({}) do |(key, value), hash|
17-
query_parameters = options.fetch(:query_parameters) { {} }
17+
query_parameters = options[:pagination].fetch(:query_parameters) { {} }
1818
params = query_parameters.merge(page: { number: value, size: collection.size }).to_query
1919

2020
hash[key] = "#{url(options)}?#{params}"
@@ -51,7 +51,7 @@ def raise_unless_any_gem_installed
5151

5252
def url(options)
5353
self_link = options.fetch(:links) {{}}
54-
self_link.fetch(:self) {} ? options[:links][:self] : options[:original_url]
54+
self_link.fetch(:self) {} ? options[:links][:self] : options[:pagination][:original_url]
5555
end
5656
end
5757
end

test/action_controller/json_api/pagination_test.rb

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,16 @@ def using_will_paginate
3131
end
3232

3333
def render_pagination_using_kaminari
34-
render json: using_kaminari, adapter: :json_api, pagination: true
34+
render json: using_kaminari, adapter: :json_api
3535
end
3636

3737
def render_pagination_using_will_paginate
38-
render json: using_will_paginate, adapter: :json_api, pagination: true
38+
render json: using_will_paginate, adapter: :json_api
3939
end
4040

4141
def render_array_without_pagination_links
42-
render json: using_will_paginate, adapter: :json_api, pagination: false
43-
end
44-
45-
def render_array_omitting_pagination_options
46-
render json: using_kaminari, adapter: :json_api
42+
setup
43+
render json: @array, adapter: :json_api
4744
end
4845
end
4946

@@ -104,12 +101,6 @@ def test_array_without_pagination_links
104101
response = JSON.parse(@response.body)
105102
refute response.key? 'links'
106103
end
107-
108-
def test_array_omitting_pagination_options
109-
get :render_array_omitting_pagination_options, page: { number: 2, size: 1 }
110-
response = JSON.parse(@response.body)
111-
refute response.key? 'links'
112-
end
113104
end
114105
end
115106
end

test/adapter/json_api/pagination_links_test.rb

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,11 @@ def using_will_paginate
2727
end
2828

2929
def data
30-
{
31-
data: [{
32-
id:"2",
33-
type:"profiles",
34-
attributes:{
35-
name:"Name 2",
36-
description:"Description 2"
37-
}
38-
}]
30+
{ data:[
31+
{ id:"1", type:"profiles", attributes:{name:"Name 1", description:"Description 1" } },
32+
{ id:"2", type:"profiles", attributes:{name:"Name 2", description:"Description 2" } },
33+
{ id:"3", type:"profiles", attributes:{name:"Name 3", description:"Description 3" } }
34+
]
3935
}
4036
end
4137

@@ -56,42 +52,48 @@ def expected_response_without_pagination_links
5652
end
5753

5854
def expected_response_with_pagination_links
59-
data.merge links
55+
{}.tap do |hash|
56+
hash[:data] = [data.values.flatten.second]
57+
hash.merge! links
58+
end
6059
end
6160

6261
def expected_response_with_pagination_links_and_additional_params
6362
new_links = links[:links].each_with_object({}) {|(key, value), hash| hash[key] = "#{value}&teste=teste" }
64-
data.merge links: new_links
63+
{}.tap do |hash|
64+
hash[:data] = [data.values.flatten.second]
65+
hash.merge! links: new_links
66+
end
6567
end
6668

6769
def test_pagination_links_using_kaminari
6870
serializer = ArraySerializer.new(using_kaminari)
69-
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer, pagination: true)
71+
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
7072

7173
assert_equal expected_response_with_pagination_links,
72-
adapter.serializable_hash(original_url: "http://example.com")
74+
adapter.serializable_hash(pagination: { original_url: "http://example.com" })
7375
end
7476

7577
def test_pagination_links_using_will_paginate
7678
serializer = ArraySerializer.new(using_will_paginate)
77-
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer, pagination: true)
79+
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
7880

7981
assert_equal expected_response_with_pagination_links,
80-
adapter.serializable_hash(original_url: "http://example.com")
82+
adapter.serializable_hash(pagination: { original_url: "http://example.com" })
8183
end
8284

8385
def test_pagination_links_with_additional_params
8486
serializer = ArraySerializer.new(using_will_paginate)
85-
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer, pagination: true)
87+
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
8688
assert_equal expected_response_with_pagination_links_and_additional_params,
87-
adapter.serializable_hash(original_url: "http://example.com",
88-
query_parameters: { teste: "teste"})
89+
adapter.serializable_hash(pagination: { original_url: "http://example.com",
90+
query_parameters: { teste: "teste"}})
8991

9092
end
9193

9294
def test_not_showing_pagination_links
93-
serializer = ArraySerializer.new(using_will_paginate)
94-
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer, pagination: false)
95+
serializer = ArraySerializer.new(@array)
96+
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
9597

9698
assert_equal expected_response_without_pagination_links, adapter.serializable_hash
9799
end

0 commit comments

Comments
 (0)