jsonapi_responses 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a729df17b8e8b391b9813a8a5c33234f9ff41893b52e4e25709a0df6e424e67
4
- data.tar.gz: 533245b43a98e243764f278a5a0290ca7e6d6d35307a068393e2db0492432f9f
3
+ metadata.gz: ab50f413d2756f7f1f6b1faae376ebaf041a60fef7df43b29c037cfdfff295c2
4
+ data.tar.gz: a3921894b3f3c0a3565e4be39667c4c9f643b9837c35c1a1e8c9c1ac491c477d
5
5
  SHA512:
6
- metadata.gz: 4abb25e296611f19b14379bb81c463d83210028ed4115453f100afa493d817234ea754e3f19211f7008bb4ab35347e4ee02516e26c44644260864aa68fb6cdba
7
- data.tar.gz: 3a8e7416b1017a718b505e041287a75512ec3aec5d73ed60e132c16d1c204a688cf135004c30ebb45c79df731c4be6f22d6fe76f2f3cf3e916c9ed10380129da
6
+ metadata.gz: 0bfebe0f3f65b8125776d5161b7c26ac0d673ae979e8ca84ebca91422ef895812260e857ee43404c5a684eeec2e816258397229d25f172b3b4875d311cd6b979
7
+ data.tar.gz: 83a0979577818624cabe42b395c12df5c1ea594768a855469ecd9de0673911bc6b6843731020f21931b81da35f8eb83582d9d99f826f19d13cfc52381d3e9955
data/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.1.0] - 2025-11-21
4
+
5
+ ### Added
6
+
7
+ - **Automatic Pagination Support**: `respond_for_index` now auto-detects Kaminari/WillPaginate pagination and includes meta automatically
8
+ - **Pagination Helpers in Responder**: Added `paginated?`, `pagination_meta`, and `render_collection_with_meta` methods
9
+ - **Smart Meta Handling**: Automatically merges pagination meta with context meta if both are present
10
+
11
+ ### Features
12
+
13
+ - Auto-detection of paginated collections (checks for `current_page`, `total_pages`, `total_count` methods)
14
+ - Automatic inclusion of pagination metadata: `current_page`, `total_pages`, `total_count`, `per_page`
15
+ - Backward compatible - works with manual `meta` in context or auto-detects pagination
16
+ - Works with both Kaminari and WillPaginate gems
17
+
18
+ ### Example Usage
19
+
20
+ ```ruby
21
+ # Controller - Automatic pagination meta
22
+ def index
23
+ @academies = Academy.page(params[:page]).per(15)
24
+ render_with(@academies) # Auto-includes pagination meta!
25
+ end
26
+
27
+ # Manual meta still works
28
+ def index
29
+ @academies = Academy.page(params[:page]).per(15)
30
+ render_with(@academies, context: { meta: { custom: 'data' } })
31
+ # Merges pagination + custom meta
32
+ end
33
+
34
+ # Custom responder with pagination helper
35
+ class MyResponder < JsonapiResponses::Responder
36
+ def render
37
+ render_collection_with_meta(record, { custom: 'meta' })
38
+ end
39
+ end
40
+ ```
41
+
3
42
  ## [1.0.0] - 2025-10-07
4
43
 
5
44
  ### 🎉 Major Release - Breaking Changes
data/README.md CHANGED
@@ -153,6 +153,154 @@ By allowing the frontend to request only the needed data, you can:
153
153
  - Avoid creating multiple endpoints for different data requirements
154
154
  - Optimize database queries based on the requested view
155
155
 
156
+ ## Automatic Pagination Support
157
+
158
+ **New in v1.1.0:** JsonapiResponses now automatically detects and handles paginated collections using Kaminari, making pagination effortless.
159
+
160
+ ### Basic Usage
161
+
162
+ When you paginate your records with Kaminari, pagination metadata is automatically included in the response:
163
+
164
+ ```ruby
165
+ class Api::V1::AcademiesController < ApplicationController
166
+ include JsonapiResponses::Respondable
167
+
168
+ def index
169
+ academies = Academy.page(params[:page]).per(15)
170
+
171
+ # That's it! Pagination is automatic
172
+ render_with(academies)
173
+ end
174
+ end
175
+ ```
176
+
177
+ **Response:**
178
+
179
+ ```json
180
+ {
181
+ "data": [
182
+ { "id": 1, "name": "Academy 1", ... },
183
+ { "id": 2, "name": "Academy 2", ... }
184
+ ],
185
+ "meta": {
186
+ "current_page": 1,
187
+ "total_pages": 5,
188
+ "total_count": 73,
189
+ "per_page": 15
190
+ }
191
+ }
192
+ ```
193
+
194
+ ### How It Works
195
+
196
+ JsonapiResponses automatically detects if your collection responds to Kaminari's pagination methods:
197
+ - `current_page`
198
+ - `total_pages`
199
+ - `total_count`
200
+
201
+ If these methods exist, pagination metadata is automatically included in the response.
202
+
203
+ ### With Custom Views
204
+
205
+ Pagination works seamlessly with different view formats:
206
+
207
+ ```ruby
208
+ def index
209
+ academies = Academy
210
+ .includes(:owner, :courses)
211
+ .page(params[:page])
212
+ .per(params[:per_page] || 15)
213
+
214
+ # Supports view parameter and automatic pagination
215
+ render_with(academies)
216
+ end
217
+ ```
218
+
219
+ **Request:**
220
+ ```
221
+ GET /api/v1/academies?page=2&per_page=20&view=summary
222
+ ```
223
+
224
+ **Response:**
225
+ ```json
226
+ {
227
+ "data": [
228
+ { "id": 21, "name": "Academy 21", ... }
229
+ ],
230
+ "meta": {
231
+ "current_page": 2,
232
+ "total_pages": 4,
233
+ "total_count": 73,
234
+ "per_page": 20
235
+ }
236
+ }
237
+ ```
238
+
239
+ ### Requirements
240
+
241
+ - **Kaminari gem** must be installed and configured
242
+ - Your collection must be paginated with `.page()` method
243
+
244
+ ### Custom Pagination Metadata
245
+
246
+ You can add additional metadata alongside automatic pagination:
247
+
248
+ ```ruby
249
+ def index
250
+ academies = Academy.page(params[:page]).per(15)
251
+
252
+ render_with(
253
+ academies,
254
+ context: { view: view },
255
+ meta: {
256
+ fetched_at: Time.current,
257
+ filters_applied: params[:search].present?
258
+ }
259
+ )
260
+ end
261
+ ```
262
+
263
+ **Response:**
264
+ ```json
265
+ {
266
+ "data": [...],
267
+ "meta": {
268
+ "current_page": 1,
269
+ "total_pages": 5,
270
+ "total_count": 73,
271
+ "per_page": 15,
272
+ "fetched_at": "2024-01-15T10:30:00Z",
273
+ "filters_applied": true
274
+ }
275
+ }
276
+ ```
277
+
278
+ ### Using Pagination Helpers
279
+
280
+ For custom responders, use the built-in pagination helpers:
281
+
282
+ ```ruby
283
+ class AcademyResponder < JsonapiResponses::Responder
284
+ def respond_for_index
285
+ if paginated?(record)
286
+ render json: {
287
+ data: serialize_collection(record, serializer_class, context),
288
+ meta: pagination_meta(record, context)
289
+ }
290
+ else
291
+ render json: {
292
+ data: serialize_collection(record, serializer_class, context)
293
+ }
294
+ end
295
+ end
296
+ end
297
+ ```
298
+
299
+ Available helpers:
300
+ - `paginated?(record)` - Check if record supports pagination
301
+ - `pagination_meta(record, context)` - Extract pagination metadata hash
302
+ - `render_collection_with_meta(record, serializer_class, context)` - Render with automatic pagination
303
+
156
304
  ## Development
157
305
 
158
306
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -212,7 +212,17 @@ module JsonapiResponses
212
212
  end
213
213
 
214
214
  def respond_for_index(record, serializer_class, context)
215
- render json: serialize_collection(record, serializer_class, context)
215
+ response = { data: serialize_collection(record, serializer_class, context) }
216
+
217
+ # Auto-detect pagination and add meta if available
218
+ if paginated?(record)
219
+ response[:meta] = pagination_meta(record, context)
220
+ elsif context[:meta]
221
+ # Allow manual meta from context
222
+ response[:meta] = context[:meta]
223
+ end
224
+
225
+ render json: response
216
226
  end
217
227
 
218
228
  def respond_for_show(record, serializer_class, context)
@@ -259,5 +269,25 @@ module JsonapiResponses
259
269
  ]
260
270
  }, status: :bad_request
261
271
  end
272
+
273
+ # Check if record is paginated (Kaminari or WillPaginate support)
274
+ def paginated?(record)
275
+ record.respond_to?(:current_page) &&
276
+ record.respond_to?(:total_pages) &&
277
+ record.respond_to?(:total_count)
278
+ end
279
+
280
+ # Extract pagination metadata from paginated record
281
+ def pagination_meta(record, context = {})
282
+ base_meta = {
283
+ current_page: record.current_page,
284
+ total_pages: record.total_pages,
285
+ total_count: record.total_count,
286
+ per_page: record.try(:limit_value) || record.try(:per_page) || context[:per_page]
287
+ }.compact
288
+
289
+ # Merge with any additional meta from context
290
+ context[:meta] ? base_meta.merge(context[:meta]) : base_meta
291
+ end
262
292
  end
263
293
  end
@@ -101,5 +101,49 @@ module JsonapiResponses
101
101
  def single_item?
102
102
  !collection?
103
103
  end
104
+
105
+ # Check if record is paginated (Kaminari or WillPaginate support)
106
+ # @return [Boolean]
107
+ def paginated?
108
+ record.respond_to?(:current_page) &&
109
+ record.respond_to?(:total_pages) &&
110
+ record.respond_to?(:total_count)
111
+ end
112
+
113
+ # Extract pagination metadata from paginated record
114
+ # @return [Hash, nil] Pagination metadata or nil if not paginated
115
+ def pagination_meta
116
+ return nil unless paginated?
117
+
118
+ {
119
+ current_page: record.current_page,
120
+ total_pages: record.total_pages,
121
+ total_count: record.total_count,
122
+ per_page: record.try(:limit_value) || record.try(:per_page)
123
+ }.compact
124
+ end
125
+
126
+ # Render collection with automatic pagination support
127
+ # @param records [Array, ActiveRecord::Relation] Records to render
128
+ # @param additional_meta [Hash] Additional metadata to include
129
+ def render_collection_with_meta(records = nil, additional_meta = {})
130
+ records ||= record
131
+ response = { data: serialize_collection(records) }
132
+
133
+ # Auto-detect pagination
134
+ if records.respond_to?(:current_page)
135
+ meta = {
136
+ current_page: records.current_page,
137
+ total_pages: records.total_pages,
138
+ total_count: records.total_count,
139
+ per_page: records.try(:limit_value) || records.try(:per_page)
140
+ }.compact
141
+ response[:meta] = meta.merge(additional_meta)
142
+ elsif additional_meta.any?
143
+ response[:meta] = additional_meta
144
+ end
145
+
146
+ render_json(response)
147
+ end
104
148
  end
105
149
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JsonapiResponses
4
- VERSION = '1.0.1'.freeze
4
+ VERSION = '1.1.0'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi_responses
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Ortega
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-08 00:00:00.000000000 Z
11
+ date: 2025-11-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: JsonapiResponses simplifies API response handling by allowing multiple
14
14
  response formats from a single endpoint, improving performance and reducing endpoint