api_only_pagination 0.1.4 → 0.2.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: 826fde0fb392a394358a65a5759171b45cc47f449785bf2877d6728f7dfb4f0e
4
- data.tar.gz: 1b13d3e52a7cdac0de53a8a54c5751283fb5e6419fdf0ac85457b74124b0e600
3
+ metadata.gz: 720784fef8ffa7a27fb958bcc70ae7389a967f99be74da4661e09202fec813ce
4
+ data.tar.gz: 1978db31fad9115663f84853648a158bac002c7f55a99fbfc21037124d026b24
5
5
  SHA512:
6
- metadata.gz: 14eb5e9588e159cc148149135bdc6ef7b2b6879394300d4aa71d6da36fc7fe8049357aab703c9f2e3488fc7290c9671bede4eda9c9b2562fbb875d962b25935a
7
- data.tar.gz: 47d8acd2be2b1f6ea72a689124156e9728404be2214232782fa733b01912e8a6875f0c62bd67eecba7c4b784d21d92ad0d5697b4f1cde2975d47e95eb3872bd5
6
+ metadata.gz: a445371db801c78c7581c12fcd3078afa5ce3d8aa4794ed15584995acec291681619433adba036afa92809bc07e1217123439792a4da1af258794b40dc543825
7
+ data.tar.gz: b0db20fc6d8e4967e8f566e7768798fa27dbe5e9d2b815181f360cd0222d444c691086d80b6e0b180adb3c70ffa5e8e78061ebf8e720a8b0fc5f8902be232db7
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.6
2
+ TargetRubyVersion: 3.2
3
3
 
4
4
  Style/StringLiterals:
5
5
  Enabled: true
@@ -11,3 +11,7 @@ Style/StringLiteralsInInterpolation:
11
11
 
12
12
  Layout/LineLength:
13
13
  Max: 120
14
+
15
+ Metrics/BlockLength:
16
+ Exclude:
17
+ - "spec/**/*"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2026-10-30
4
+
5
+ - **Breaking:** require Ruby >= 3.2 and ActiveRecord >= 6.1 (the versions CI tests)
6
+ - **Breaking:** remove the `paginate` alias, which clashed with will_paginate; use `do_paginate` or `paginated_response`
7
+ - Add `next_page` and `previous_page` to the response
8
+ - Add `PaginatedData#to_h` and an explicit `#as_json`; serializer options such as `only:` apply to the records in `data`
9
+ - Add `render_paginated` controller helper (ActionController::Base and ::API) that reads `page`/`per_page` from params, with opt-in `X-Total-Count`/`Link` pagination headers (`pagination_headers` setting)
10
+ - Note: Rails 8.1 does not load on Ruby 3.3.0 because of a Ruby parser bug fixed in 3.3.1; use a later 3.3.x
11
+
12
+ ## [0.1.5] - 2026-10-30
13
+
14
+ - Fix: negative `page`/`per_page` values produced invalid SQL; any value that isn't a positive integer now falls back to the configured default
15
+ - Fix: paginating relations with `group` or a custom `select` raised errors while counting
16
+ - Fix: `last_page?` returned false for empty results and for pages past the end
17
+ - Remove a no-op `ActiveRecord::Relation.include`; chained calls such as `User.where(...).do_paginate` are unaffected
18
+ - Add a real spec suite (in-memory SQLite) and CI across Ruby 3.2–3.4 and ActiveRecord 6.1–8.1
19
+
3
20
  ## [0.1.0] - 2023-03-23
4
21
 
5
22
  - Initial release
data/Gemfile CHANGED
@@ -5,6 +5,9 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in api_only_pagination.gemspec
6
6
  gemspec
7
7
 
8
+ gem "actionpack"
8
9
  gem "rake", "~> 13.0"
9
10
 
10
11
  gem "rubocop", "~> 1.21"
12
+
13
+ gem "sqlite3", "~> 1.4"
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- api_only_pagination (0.1.4)
5
- activerecord (>= 5.0)
4
+ api_only_pagination (0.2.0)
5
+ activerecord (>= 6.1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -32,39 +32,39 @@ GEM
32
32
  tzinfo (~> 2.0)
33
33
  zeitwerk (~> 2.3)
34
34
  ast (2.4.2)
35
- builder (3.2.4)
35
+ builder (3.3.0)
36
36
  concurrent-ruby (1.2.2)
37
- crass (1.0.6)
37
+ crass (1.0.8)
38
38
  diff-lcs (1.5.0)
39
- erubi (1.12.0)
39
+ erubi (1.13.1)
40
40
  i18n (1.13.0)
41
41
  concurrent-ruby (~> 1.0)
42
42
  json (2.6.1)
43
- loofah (2.20.0)
43
+ loofah (2.25.2)
44
44
  crass (~> 1.0.2)
45
- nokogiri (>= 1.5.9)
46
- method_source (1.0.0)
45
+ nokogiri (>= 1.12.0)
47
46
  minitest (5.18.0)
48
- nokogiri (1.13.10-x86_64-darwin)
47
+ nokogiri (1.19.4-arm64-darwin)
48
+ racc (~> 1.4)
49
+ nokogiri (1.19.4-x86_64-darwin)
50
+ racc (~> 1.4)
51
+ nokogiri (1.19.4-x86_64-linux-gnu)
49
52
  racc (~> 1.4)
50
53
  parallel (1.21.0)
51
- parser (3.2.1.1)
54
+ parser (3.3.13.0)
52
55
  ast (~> 2.4.1)
53
- racc (1.6.2)
54
- rack (2.2.7)
55
- rack-test (2.1.0)
56
+ racc
57
+ racc (1.8.1)
58
+ rack (2.2.25)
59
+ rack-test (2.3.0)
56
60
  rack (>= 1.3)
57
- rails-dom-testing (2.0.3)
58
- activesupport (>= 4.2.0)
61
+ rails-dom-testing (2.3.0)
62
+ activesupport (>= 5.0.0)
63
+ minitest
59
64
  nokogiri (>= 1.6)
60
- rails-html-sanitizer (1.5.0)
61
- loofah (~> 2.19, >= 2.19.1)
62
- railties (6.1.7.3)
63
- actionpack (= 6.1.7.3)
64
- activesupport (= 6.1.7.3)
65
- method_source
66
- rake (>= 12.2)
67
- thor (~> 1.0)
65
+ rails-html-sanitizer (1.7.1)
66
+ loofah (~> 2.25, >= 2.25.2)
67
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
68
68
  rainbow (3.1.1)
69
69
  rake (13.0.6)
70
70
  regexp_parser (2.3.0)
@@ -81,14 +81,6 @@ GEM
81
81
  rspec-mocks (3.10.2)
82
82
  diff-lcs (>= 1.2.0, < 2.0)
83
83
  rspec-support (~> 3.10.0)
84
- rspec-rails (4.0.2)
85
- actionpack (>= 4.2)
86
- activesupport (>= 4.2)
87
- railties (>= 4.2)
88
- rspec-core (~> 3.10)
89
- rspec-expectations (~> 3.10)
90
- rspec-mocks (~> 3.10)
91
- rspec-support (~> 3.10)
92
84
  rspec-support (3.10.2)
93
85
  rubocop (1.48.1)
94
86
  json (~> 2.3)
@@ -103,21 +95,26 @@ GEM
103
95
  rubocop-ast (1.27.0)
104
96
  parser (>= 3.2.1.0)
105
97
  ruby-progressbar (1.11.0)
106
- thor (1.2.1)
98
+ sqlite3 (1.7.3-arm64-darwin)
99
+ sqlite3 (1.7.3-x86_64-darwin)
100
+ sqlite3 (1.7.3-x86_64-linux)
107
101
  tzinfo (2.0.6)
108
102
  concurrent-ruby (~> 1.0)
109
103
  unicode-display_width (2.4.2)
110
104
  zeitwerk (2.6.8)
111
105
 
112
106
  PLATFORMS
107
+ arm64-darwin-25
113
108
  x86_64-darwin-20
109
+ x86_64-linux
114
110
 
115
111
  DEPENDENCIES
112
+ actionpack
116
113
  api_only_pagination!
117
114
  rake (~> 13.0)
118
115
  rspec (~> 3.6)
119
- rspec-rails (~> 4.0)
120
116
  rubocop (~> 1.21)
117
+ sqlite3 (~> 1.4)
121
118
 
122
119
  BUNDLED WITH
123
120
  2.4.9
data/README.md CHANGED
@@ -9,45 +9,86 @@ or add it to your Gemfile
9
9
  ```
10
10
  gem 'api_only_pagination'
11
11
  ```
12
+ ## Requirements
13
+
14
+ Ruby 3.2+ and ActiveRecord 6.1+. Versions 0.1.x support older Rubies and Rails but are no longer maintained.
15
+
12
16
  ## Usage
13
17
 
14
- Configure your pagination adding api_only_pagination.rb file in config/initializers unless it will take default configurations.
15
-
16
- ```
17
- ApiOnlyPagination.configure do |config|
18
- config.default_page_size = 3
19
- config.max_per_page = 100
20
- config.default_page = 1
21
- end
22
- ```
18
+ Optionally configure defaults in `config/initializers/api_only_pagination.rb`:
19
+
20
+ ```ruby
21
+ ApiOnlyPagination.configure do |config|
22
+ config.default_page_size = 20 # per_page when none (or an invalid value) is given
23
+ config.max_per_page = 100 # upper limit for per_page
24
+ config.default_page = 1 # page when none (or an invalid value) is given
25
+ config.pagination_headers = false # see "In controllers"
26
+ end
27
+ ```
28
+
29
+ Call `do_paginate(page, per_page)` on any model or relation:
30
+
31
+ ```ruby
32
+ result = User.where(active: true).order(:id).do_paginate(params[:page], params[:per_page])
33
+ render json: result
34
+ ```
35
+
36
+ `page` and `per_page` can come straight from request params. Strings are converted to integers, any value that isn't a positive integer falls back to the configured default, and `per_page` is capped at `max_per_page`.
37
+
38
+ `do_paginate` returns an `ApiOnlyPagination::PaginatedData` object. It renders as:
39
+
40
+ ```json
41
+ {
42
+ "data": [{ "id": 3, "name": "..." }, { "id": 4, "name": "..." }],
43
+ "per_page": 2,
44
+ "current_page": 2,
45
+ "total_pages": 3,
46
+ "total_records": 5,
47
+ "next_page": 3,
48
+ "previous_page": 1
49
+ }
50
+ ```
51
+
52
+ `next_page` and `previous_page` are `null` on the last and first page. Serializer options apply to the records, so `render json: result, only: [:id, :name]` limits the fields in `data` and keeps the pagination fields. Use `result.to_h` for a symbol-keyed hash, or read the attributes directly (`result.data`, `result.total_pages`, ...).
53
+
54
+ ### In controllers
55
+
56
+ `render_paginated` reads `page` and `per_page` from params, paginates, renders the JSON above and returns the result:
57
+
58
+ ```ruby
59
+ class UsersController < ApplicationController
60
+ def index
61
+ render_paginated User.where(active: true).order(:id)
62
+ end
63
+ end
64
+ ```
65
+
66
+ Other options go to `render`, so `render_paginated scope, only: [:id, :name], status: :ok` works. Pass `page:` or `per_page:` to override params.
67
+
68
+ The helper can also set pagination headers: `X-Total-Count`, `X-Total-Pages`, `X-Per-Page`, `X-Page`, and a `Link` header with `first`/`prev`/`next`/`last` URLs that keep the request's other query params. Turn them on for one call with `render_paginated scope, pagination_headers: true`, or for every call:
23
69
 
24
- Now you can call chain .do_paginate(page, per_page) to your activerecord query.
70
+ ```ruby
71
+ ApiOnlyPagination.configure do |config|
72
+ config.pagination_headers = true
73
+ end
25
74
  ```
26
- response = User.do_paginate(1,20)
27
- ```
28
75
 
29
- The response will be
76
+ If browser clients need to read these headers in a cross-origin setup, add them to `expose` in your CORS config.
30
77
 
31
-
32
- {
33
- "data" => [],
34
- "per_page" => 3,
35
- "current_page" => 1,
36
- "total_pages" => 2,
37
- "total_records" => 5
38
- }
39
-
78
+ ### Upgrading from 0.1.x
40
79
 
80
+ - The `paginate` alias was removed because it clashes with will_paginate. Use `do_paginate` (or `paginated_response`).
81
+ - The response has two new fields, `next_page` and `previous_page`.
41
82
 
42
83
  ## Development
43
84
 
44
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
85
+ After checking out the repo, run `bin/setup` to install dependencies, then `bundle exec rake` to run the specs and RuboCop. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
45
86
 
46
87
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
47
88
 
48
89
  ## Contributing
49
90
 
50
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/api_only_pagination. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/api_only_pagination/blob/master/CODE_OF_CONDUCT.md).
91
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ashok1/api_only_pagination. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/ashok1/api_only_pagination/blob/main/CODE_OF_CONDUCT.md).
51
92
 
52
93
  ## License
53
94
 
@@ -55,4 +96,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
55
96
 
56
97
  ## Code of Conduct
57
98
 
58
- Everyone interacting in the ApiOnlyPagination project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/api_only_pagination/blob/master/CODE_OF_CONDUCT.md).
99
+ Everyone interacting in the ApiOnlyPagination project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ashok1/api_only_pagination/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
4
5
  require "rubocop/rake_task"
5
6
 
7
+ RSpec::Core::RakeTask.new(:spec)
6
8
  RuboCop::RakeTask.new
7
9
 
8
- task default: :rubocop
10
+ task default: %i[spec rubocop]
@@ -3,12 +3,16 @@
3
3
  require "active_record"
4
4
 
5
5
  module ApiOnlyPagination
6
+ # Adds do_paginate (and its aliases) to every ActiveRecord model and, through delegation, to relations
6
7
  module ActiveRecordPaginate
7
8
  extend ActiveSupport::Concern
9
+
10
+ # Pagination entry points available on models and relations
8
11
  module ClassMethods
9
- %i[do_paginate paginate paginated_response].each do |access_method|
10
- define_method(access_method) do |page = ApiOnlyPagination.configuration.default_page, per_page = ApiOnlyPagination.configuration.default_page_size| # or even |*args|
11
- pagination = ApiOnlyPagination::Pagination.new(all, { page: page, per_page: per_page })
12
+ %i[do_paginate paginated_response].each do |access_method|
13
+ # nil page/per_page fall back to the configured defaults in Paginate
14
+ define_method(access_method) do |page = nil, per_page = nil|
15
+ pagination = ApiOnlyPagination::Pagination.new(all, { page:, per_page: })
12
16
  meta_data = pagination.metadata
13
17
 
14
18
  ApiOnlyPagination::PaginatedData
@@ -16,9 +20,11 @@ module ApiOnlyPagination
16
20
  per_page: meta_data.per_page,
17
21
  current_page: meta_data.page,
18
22
  total_pages: meta_data.total_pages,
19
- total_records: meta_data.count)
23
+ total_records: meta_data.count,
24
+ next_page: meta_data.next_page,
25
+ previous_page: meta_data.previous_page)
20
26
  end
21
- end
27
+ end
22
28
  end
23
29
  end
24
30
  end
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApiOnlyPagination
4
+ # Global settings, changed through ApiOnlyPagination.configure
4
5
  class Configuration
5
- attr_accessor :default_page_size, :max_per_page, :default_page
6
+ attr_accessor :default_page_size, :max_per_page, :default_page, :pagination_headers
6
7
 
7
8
  def initialize
8
9
  @default_page_size = 20
9
10
  @max_per_page = 100
10
11
  @default_page = 1
12
+ @pagination_headers = false
11
13
  end
12
14
  end
13
15
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApiOnlyPagination
4
+ # Controller helper, included into ActionController::Base and ActionController::API on load
5
+ module Controller
6
+ private
7
+
8
+ # Paginates scope with page/per_page from params, renders it as JSON and returns the PaginatedData.
9
+ # Remaining options go to render, e.g. render_paginated(User.all, only: [:id, :name], status: :ok)
10
+ def render_paginated(scope, page: params[:page], per_page: params[:per_page],
11
+ pagination_headers: ApiOnlyPagination.configuration.pagination_headers, **render_options)
12
+ result = scope.do_paginate(page, per_page)
13
+ add_pagination_headers(result) if pagination_headers
14
+ render(json: result, **render_options)
15
+ result
16
+ end
17
+
18
+ def add_pagination_headers(result)
19
+ {
20
+ "X-Total-Count" => result.total_records,
21
+ "X-Total-Pages" => result.total_pages,
22
+ "X-Per-Page" => result.per_page,
23
+ "X-Page" => result.current_page,
24
+ "Link" => pagination_link_header(result).presence
25
+ }.compact.each { |name, value| response.headers[name] = value.to_s }
26
+ end
27
+
28
+ def pagination_link_header(result)
29
+ return "" if result.total_pages.zero?
30
+
31
+ { first: 1, prev: result.previous_page, next: result.next_page, last: result.total_pages }
32
+ .filter_map { |rel, page| %(<#{pagination_url(page, result.per_page)}>; rel="#{rel}") if page }
33
+ .join(", ")
34
+ end
35
+
36
+ def pagination_url(page, per_page)
37
+ query = request.query_parameters.merge("page" => page, "per_page" => per_page).to_query
38
+ "#{request.base_url}#{request.path}?#{query}"
39
+ end
40
+ end
41
+ end
@@ -1,27 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApiOnlyPagination
4
+ # Normalizes page/per_page input and computes page metadata from a record count
4
5
  class Paginate
5
6
  attr_reader :page, :count, :per_page
6
7
 
7
8
  def initialize(page, per_page, count)
8
- @page = (page || ApiOnlyPagination.configuration.default_page).to_i
9
+ config = ApiOnlyPagination.configuration
10
+ @page = positive_integer(page) || config.default_page
9
11
  @count = count
10
- @per_page = [(per_page.to_i || ApiOnlyPagination.configuration.default_page_size),
11
- ApiOnlyPagination.configuration.max_per_page].min
12
-
13
- validate_params
14
- end
15
-
16
- def validate_params
17
- @page = @page.zero? ? ApiOnlyPagination.configuration.default_page : @page
18
- @per_page = @per_page.zero? ? ApiOnlyPagination.configuration.default_page_size : @per_page
12
+ @per_page = [positive_integer(per_page) || config.default_page_size, config.max_per_page].min
19
13
  end
20
14
 
21
15
  def offset
22
- return 0 if page == 1
23
-
24
- per_page * (page.to_i - 1)
16
+ per_page * (page - 1)
25
17
  end
26
18
 
27
19
  def next_page
@@ -41,7 +33,7 @@ module ApiOnlyPagination
41
33
  end
42
34
 
43
35
  def last_page?
44
- page == total_pages
36
+ page >= total_pages
45
37
  end
46
38
 
47
39
  def first_page?
@@ -51,5 +43,13 @@ module ApiOnlyPagination
51
43
  def total_pages
52
44
  (count / per_page.to_f).ceil
53
45
  end
46
+
47
+ private
48
+
49
+ # nil, zero, negative and non-numeric values (e.g. "abc") all become nil
50
+ def positive_integer(value)
51
+ integer = value.to_i
52
+ integer if integer.positive?
53
+ end
54
54
  end
55
55
  end
@@ -2,20 +2,42 @@
2
2
 
3
3
  # Main module
4
4
  module ApiOnlyPagination
5
- # Response object class
5
+ # Response object returned by do_paginate; serializes to the documented JSON shape
6
6
  class PaginatedData
7
7
  attr_accessor :data,
8
8
  :per_page,
9
9
  :current_page,
10
10
  :total_pages,
11
- :total_records
11
+ :total_records,
12
+ :next_page,
13
+ :previous_page
12
14
 
13
- def initialize(data:, per_page:, current_page:, total_pages:, total_records:)
15
+ def initialize(data:, per_page:, current_page:, total_pages:, total_records:, next_page: nil, previous_page: nil) # rubocop:disable Metrics/ParameterLists
14
16
  @data = data
15
17
  @per_page = per_page
16
18
  @current_page = current_page
17
19
  @total_pages = total_pages
18
20
  @total_records = total_records
21
+ @next_page = next_page
22
+ @previous_page = previous_page
23
+ end
24
+
25
+ def to_h
26
+ {
27
+ data:,
28
+ per_page:,
29
+ current_page:,
30
+ total_pages:,
31
+ total_records:,
32
+ next_page:,
33
+ previous_page:
34
+ }
35
+ end
36
+
37
+ # Serializer options (only:, except:, include:, methods:) apply to the records in data,
38
+ # so `render json: result, only: [:id, :name]` works as it would for the bare relation.
39
+ def as_json(options = nil)
40
+ to_h.merge(data: data.as_json(options)).as_json
19
41
  end
20
42
  end
21
43
  end
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApiOnlyPagination
4
+ # Counts a relation and applies limit/offset for the requested page
4
5
  class Pagination
5
6
  attr_reader :collection, :params
6
7
 
7
8
  def initialize(collection, params = {})
8
9
  @collection = collection
9
- @params = params.merge(count: collection.count)
10
+ @params = params.merge(count: total_count)
10
11
  end
11
12
 
12
13
  def metadata
@@ -18,5 +19,13 @@ module ApiOnlyPagination
18
19
  .limit(metadata.per_page)
19
20
  .offset(metadata.offset)
20
21
  end
22
+
23
+ private
24
+
25
+ # count(:all) ignores custom selects; grouped relations return a Hash of group => count
26
+ def total_count
27
+ count = collection.count(:all)
28
+ count.is_a?(Hash) ? count.size : count
29
+ end
21
30
  end
22
31
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApiOnlyPagination
4
- VERSION = "0.1.4"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -7,7 +7,9 @@ require_relative "api_only_pagination/paginate"
7
7
  require_relative "api_only_pagination/pagination"
8
8
  require_relative "api_only_pagination/paginated_data"
9
9
  require_relative "api_only_pagination/active_record_paginate"
10
+ require_relative "api_only_pagination/controller"
10
11
 
12
+ # Offset pagination for ActiveRecord that returns data plus page metadata for API responses
11
13
  module ApiOnlyPagination
12
14
  class << self
13
15
  def configuration
@@ -26,5 +28,9 @@ end
26
28
 
27
29
  ActiveSupport.on_load(:active_record) do
28
30
  include ApiOnlyPagination::ActiveRecordPaginate
29
- ActiveRecord::Relation.include(ApiOnlyPagination::ActiveRecordPaginate)
31
+ end
32
+
33
+ # Fires for both ActionController::Base and ActionController::API; does nothing in apps without ActionPack
34
+ ActiveSupport.on_load(:action_controller) do
35
+ include ApiOnlyPagination::Controller
30
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_only_pagination
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ashok
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-13 00:00:00.000000000 Z
11
+ date: 2026-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.0'
19
+ version: '6.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '5.0'
26
+ version: '6.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.6'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec-rails
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '4.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '4.0'
55
41
  description: pagination with api response only
56
42
  email:
57
43
  - kingkoirala1@gmail.com
@@ -59,6 +45,7 @@ executables: []
59
45
  extensions: []
60
46
  extra_rdoc_files: []
61
47
  files:
48
+ - ".rspec"
62
49
  - ".rubocop.yml"
63
50
  - CHANGELOG.md
64
51
  - CODE_OF_CONDUCT.md
@@ -67,10 +54,10 @@ files:
67
54
  - LICENSE.txt
68
55
  - README.md
69
56
  - Rakefile
70
- - api_only_pagination.gemspec
71
57
  - lib/api_only_pagination.rb
72
58
  - lib/api_only_pagination/active_record_paginate.rb
73
59
  - lib/api_only_pagination/configuration.rb
60
+ - lib/api_only_pagination/controller.rb
74
61
  - lib/api_only_pagination/paginate.rb
75
62
  - lib/api_only_pagination/paginated_data.rb
76
63
  - lib/api_only_pagination/pagination.rb
@@ -90,14 +77,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
90
77
  requirements:
91
78
  - - ">="
92
79
  - !ruby/object:Gem::Version
93
- version: 2.6.0
80
+ version: 3.2.0
94
81
  required_rubygems_version: !ruby/object:Gem::Requirement
95
82
  requirements:
96
83
  - - ">="
97
84
  - !ruby/object:Gem::Version
98
85
  version: '0'
99
86
  requirements: []
100
- rubygems_version: 3.2.16
87
+ rubygems_version: 3.5.3
101
88
  signing_key:
102
89
  specification_version: 4
103
90
  summary: pagination with api response only
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/api_only_pagination/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "api_only_pagination"
7
- spec.version = ApiOnlyPagination::VERSION
8
- spec.authors = ["Ashok"]
9
- spec.email = ["kingkoirala1@gmail.com"]
10
-
11
- spec.summary = "pagination with api response only"
12
- spec.description = "pagination with api response only"
13
- spec.homepage = "https://github.com/ashok1/api_only_pagination"
14
- spec.license = "MIT"
15
- spec.required_ruby_version = ">= 2.6.0"
16
-
17
- # spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
18
-
19
- spec.metadata["homepage_uri"] = spec.homepage
20
- spec.metadata["source_code_uri"] = spec.homepage
21
-
22
- # Specify which files should be added to the gem when it is released.
23
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
- spec.files = Dir.chdir(__dir__) do
25
- `git ls-files -z`.split("\x0").reject do |f|
26
- (File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
27
- end
28
- end
29
- spec.bindir = "exe"
30
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
- spec.require_paths = ["lib"]
32
- spec.add_dependency "activerecord", ">= 5.0"
33
- spec.add_development_dependency "rspec", "~> 3.6"
34
- spec.add_development_dependency "rspec-rails", "~> 4.0"
35
- # Uncomment to register a new dependency of your gem
36
- # spec.add_dependency "example-gem", "~> 1.0"
37
-
38
- # For more information and examples about making a new gem, check out our
39
- # guide at: https://bundler.io/guides/creating_gem.html
40
- end