nueca_rails_interfaces 1.2.8 → 1.2.9
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 +4 -4
- data/lib/nueca_rails_interfaces/v2/pagination/base_adapter.rb +20 -0
- data/lib/nueca_rails_interfaces/v2/pagination/kaminari_adapter.rb +18 -0
- data/lib/nueca_rails_interfaces/v2/pagination/pagy_adapter.rb +20 -0
- data/lib/nueca_rails_interfaces/v2/pagination/will_paginate_adapter.rb +18 -0
- data/lib/nueca_rails_interfaces/v2/query_interface.rb +162 -0
- data/lib/nueca_rails_interfaces/v3/form_interface.rb +3 -3
- data/lib/nueca_rails_interfaces/version.rb +1 -1
- metadata +12 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 06fa9d84241065bed1906ea3c75590d9d3651ad508e4994653e5edfc7f7f9b60
|
|
4
|
+
data.tar.gz: 1a08ad66325e0db8c57f2601115bee93d00490b4f59d4aaf0226c7a06cebdc39
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cc1c35a7af8f4e6e871ff6d0445f27fc4405faae4f8e2ed9fd6b1c51652b6688c2d708e63a8ae4697d4ed500a2ba40086307a81150953e7f3c2a9eef73e3355a
|
|
7
|
+
data.tar.gz: ac34f696efc3b533c3bbb0c5d19aa1806b18c457f80fb28e8908f07631a8d02d28ff145d444ed960a63ba8f3d033cccf4f125ab94a01fd0eefa7c035caf3ea9d
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NuecaRailsInterfaces
|
|
4
|
+
module V2
|
|
5
|
+
module Pagination
|
|
6
|
+
# Base adapter module for pagination strategies
|
|
7
|
+
# Modules must implement the .paginate(collection, page, per_page) method
|
|
8
|
+
module BaseAdapter
|
|
9
|
+
# Paginate the collection based on the provided page and per page values.
|
|
10
|
+
# @param [ActiveRecord::Relation] collection The collection to be paginated.
|
|
11
|
+
# @param [Integer] page The page number.
|
|
12
|
+
# @param [Integer] per_page The number of records per page.
|
|
13
|
+
# @return [ActiveRecord::Relation] The paginated collection.
|
|
14
|
+
def paginate(collection, page, per_page)
|
|
15
|
+
raise NotImplementedError, "#{name} must implement the .paginate(collection, page, per_page) method"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_adapter'
|
|
4
|
+
|
|
5
|
+
module NuecaRailsInterfaces
|
|
6
|
+
module V2
|
|
7
|
+
module Pagination
|
|
8
|
+
# Adapter for Kaminari gem.
|
|
9
|
+
module KaminariAdapter
|
|
10
|
+
extend BaseAdapter
|
|
11
|
+
|
|
12
|
+
def self.paginate(collection, page, per_page)
|
|
13
|
+
collection.page(page).per(per_page)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_adapter'
|
|
4
|
+
|
|
5
|
+
module NuecaRailsInterfaces
|
|
6
|
+
module V2
|
|
7
|
+
module Pagination
|
|
8
|
+
# Adapter for Pagy gem.
|
|
9
|
+
module PagyAdapter
|
|
10
|
+
extend BaseAdapter
|
|
11
|
+
|
|
12
|
+
def self.paginate(collection, page, per_page)
|
|
13
|
+
@helper ||= Class.new { include ::Pagy::Backend }.new
|
|
14
|
+
_pagy, records = @helper.send(:pagy, collection, page: page, items: per_page)
|
|
15
|
+
records
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_adapter'
|
|
4
|
+
|
|
5
|
+
module NuecaRailsInterfaces
|
|
6
|
+
module V2
|
|
7
|
+
module Pagination
|
|
8
|
+
# Adapter for WillPaginate gem.
|
|
9
|
+
module WillPaginateAdapter
|
|
10
|
+
extend BaseAdapter
|
|
11
|
+
|
|
12
|
+
def self.paginate(collection, page, per_page)
|
|
13
|
+
collection.paginate(page: page, per_page: per_page)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'pagination/base_adapter'
|
|
4
|
+
require_relative 'pagination/will_paginate_adapter'
|
|
5
|
+
require_relative 'pagination/kaminari_adapter'
|
|
6
|
+
require_relative 'pagination/pagy_adapter'
|
|
7
|
+
|
|
8
|
+
module NuecaRailsInterfaces
|
|
9
|
+
module V2
|
|
10
|
+
# V2 Query Interface is the same as V1 Query Interface,
|
|
11
|
+
# but with changes in the pagination logic.
|
|
12
|
+
# V1 had tight coupling with WillPaginate, this version decouples the query interface from it,
|
|
13
|
+
# allowing for custom pagination adapters to be used.
|
|
14
|
+
module QueryInterface
|
|
15
|
+
# The basis for validity of pagination settings. It also contains default values.
|
|
16
|
+
VALID_PAGINATION_HASH = {
|
|
17
|
+
max: 20, # Absolute maximum number of records per page, even if the query requests for more.
|
|
18
|
+
min: 1, # Absolute minimum number of records per page, even if the query requests for less.
|
|
19
|
+
per_page: 20, # Default number of records per page if not specified in the query.
|
|
20
|
+
page: 1 # Default page number if not specified in the query.
|
|
21
|
+
}.freeze
|
|
22
|
+
|
|
23
|
+
# Basis for considering a non-paging result even when the query is being processed for pagination.
|
|
24
|
+
# This number states the invalidity of pagination, but it exists for legacy support.
|
|
25
|
+
NO_PAGING_THRESHOLD = 1_000_000
|
|
26
|
+
|
|
27
|
+
class << self
|
|
28
|
+
def included(base)
|
|
29
|
+
# This is the method to call outside this object to apply the query filters, sortings and paginations.
|
|
30
|
+
# @param [Hash] query The query parameters.
|
|
31
|
+
# @param [ActiveRecord::Relation] collection The collection to be queried.
|
|
32
|
+
base.define_singleton_method(:call) do |query, collection|
|
|
33
|
+
new(query, collection).call
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
attr_reader :query, :collection
|
|
39
|
+
|
|
40
|
+
# Do not override! This is how we will always initialize our query objects.
|
|
41
|
+
# No processing should be done in the initialize method.
|
|
42
|
+
# @param [Hash] query The query parameters.
|
|
43
|
+
# @param [ActiveRecord::Relation] collection The collection to be queried.
|
|
44
|
+
def initialize(query, collection, pagination: true)
|
|
45
|
+
@query = query
|
|
46
|
+
@collection = collection
|
|
47
|
+
@pagination_flag = pagination
|
|
48
|
+
query_aliases
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Do not override. This is the method to call outside this object
|
|
52
|
+
# to apply the query filters, sortings and paginations.
|
|
53
|
+
def call
|
|
54
|
+
apply_filters!
|
|
55
|
+
apply_sorting!
|
|
56
|
+
apply_pagination!
|
|
57
|
+
collection
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
# Place here filters. Be sure to assign @collection to override the original collection. Be sure it is private!
|
|
63
|
+
def filters; end
|
|
64
|
+
|
|
65
|
+
# Place here sorting logic. Be sure to assign @collection to override the original collection.
|
|
66
|
+
# Be sure it is private!
|
|
67
|
+
def sorts; end
|
|
68
|
+
|
|
69
|
+
# Pagination settings to modify the default behavior of a query object.
|
|
70
|
+
# Default values are in VALID_PAGINATION_HASH constant.
|
|
71
|
+
# Override the method to change the default values.
|
|
72
|
+
def pagination_settings
|
|
73
|
+
{}
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Always updated alias of filters.
|
|
77
|
+
def apply_filters!
|
|
78
|
+
filters
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Always updated alias of sorts.
|
|
82
|
+
def apply_sorting!
|
|
83
|
+
sorts
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Paginates the collection based on query or settings.
|
|
87
|
+
def apply_pagination!
|
|
88
|
+
raise 'Invalid pagination settings.' unless correct_pagination_settings? # rubocop:disable Style/ImplicitRuntimeError
|
|
89
|
+
return unless @pagination_flag
|
|
90
|
+
|
|
91
|
+
@collection = pagination_adapter.paginate(collection, fetch_page_value, fetch_per_page_value)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Selects the appropriate pagination adapter based on loaded gems.
|
|
95
|
+
# The first adapter found will be used.
|
|
96
|
+
# The adapters are checked in the following order: WillPaginate, Kaminari, Pagy.
|
|
97
|
+
# Override this method if using custom pagination adapter.
|
|
98
|
+
# @return [NuecaRailsInterfaces::V2::Pagination::BaseAdapter] The pagination adapter.
|
|
99
|
+
def pagination_adapter
|
|
100
|
+
@pagination_adapter ||=
|
|
101
|
+
if defined?(::WillPaginate)
|
|
102
|
+
NuecaRailsInterfaces::V2::Pagination::WillPaginateAdapter
|
|
103
|
+
elsif defined?(::Kaminari)
|
|
104
|
+
NuecaRailsInterfaces::V2::Pagination::KaminariAdapter
|
|
105
|
+
elsif defined?(::Pagy)
|
|
106
|
+
NuecaRailsInterfaces::V2::Pagination::PagyAdapter
|
|
107
|
+
else
|
|
108
|
+
# rubocop:disable Style/ImplicitRuntimeError
|
|
109
|
+
raise 'No compatible pagination library detected (WillPaginate, Kaminari, or Pagy) ' \
|
|
110
|
+
'and collection does not respond to :paginate.'
|
|
111
|
+
# rubocop:enable Style/ImplicitRuntimeError
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Logic for fetching the page value from the query or settings.
|
|
116
|
+
def fetch_page_value
|
|
117
|
+
query&.key?(:page) ? query[:page].to_i : merged_pagination_settings[:page]
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Logic for fetching the per page value from the query or settings.
|
|
121
|
+
def fetch_per_page_value
|
|
122
|
+
per_page = query&.key?(:per_page) ? query[:per_page].to_i : merged_pagination_settings[:per_page]
|
|
123
|
+
per_page.clamp(merged_pagination_settings[:min], merged_pagination_settings[:max])
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Checks if the pagination settings are correct.
|
|
127
|
+
# The app crashes on misconfiguration.
|
|
128
|
+
def correct_pagination_settings?
|
|
129
|
+
return false unless pagination_settings.is_a?(Hash)
|
|
130
|
+
|
|
131
|
+
detected_keys = []
|
|
132
|
+
merged_pagination_settings.each_key do |key|
|
|
133
|
+
return false unless VALID_PAGINATION_HASH.key?(key)
|
|
134
|
+
|
|
135
|
+
detected_keys << key
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
detected_keys.sort == VALID_PAGINATION_HASH.keys.sort
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# The final result of pagination settings, and thus the used one.
|
|
142
|
+
def merged_pagination_settings
|
|
143
|
+
@merged_pagination_settings ||= VALID_PAGINATION_HASH.merge(pagination_settings)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Aliases for query parameters for legacy support.
|
|
147
|
+
# No need to override this in children. Directly modify this method in this interface if need be.
|
|
148
|
+
def query_aliases
|
|
149
|
+
query[:per_page] = query[:limit] if query[:limit].present? && query[:per_page].blank?
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# For deprecation. Use this for queries that do not need pagination.
|
|
153
|
+
# Queries will still be paginated as a result, but with the use of the threshold,
|
|
154
|
+
# the result is as good as a non-paginated result,
|
|
155
|
+
# and it will be treated as such.
|
|
156
|
+
def no_pagination
|
|
157
|
+
Rails.logger.warn 'Querying without paging is deprecated. Enforce paging in queries!'
|
|
158
|
+
{ max: NO_PAGING_THRESHOLD, min: NO_PAGING_THRESHOLD }
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -7,7 +7,7 @@ module NuecaRailsInterfaces
|
|
|
7
7
|
#
|
|
8
8
|
# Models managed by the form are declared explicitly with the `model` macro.
|
|
9
9
|
# Their attributes arrive as a nested hash keyed by the model name, which is
|
|
10
|
-
# what `fields_for :school_year, f.object.school_year` produces in the view
|
|
10
|
+
# what `fields_for :school_year, f.object.school_year` produces in the view;
|
|
11
11
|
# e.g. `school_year: { name: "..." }`. This maps directly to:
|
|
12
12
|
# `params.expect(my_form: [{ school_year: [:name] }, :other_field])`
|
|
13
13
|
#
|
|
@@ -80,7 +80,7 @@ module NuecaRailsInterfaces
|
|
|
80
80
|
|
|
81
81
|
# Builds the model instance from the given attributes hash, assigning only
|
|
82
82
|
# fields the model recognises. Unknown fields are silently discarded.
|
|
83
|
-
# `attrs` may be a plain Hash or ActionController::Parameters
|
|
83
|
+
# `attrs` may be a plain Hash or ActionController::Parameters; both are
|
|
84
84
|
# normalised to a plain Hash before processing; field whitelisting via
|
|
85
85
|
# Splits options into model instances and regular form attributes.
|
|
86
86
|
# Hash-valued keys matching a declared model are built into model instances.
|
|
@@ -153,7 +153,7 @@ module NuecaRailsInterfaces
|
|
|
153
153
|
|
|
154
154
|
# Returns a merged hash of model instances and regular form attributes.
|
|
155
155
|
# Defined here (included, not prepended) so that a form class can override it
|
|
156
|
-
# by defining its own `attributes` method
|
|
156
|
+
# by defining its own `attributes` method; the class-level definition is found
|
|
157
157
|
# first in the MRO, falling back to this default when no override exists.
|
|
158
158
|
def attributes
|
|
159
159
|
result = {}
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nueca_rails_interfaces
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tien
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: exe
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-06-24 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: rails
|
|
@@ -43,6 +44,7 @@ dependencies:
|
|
|
43
44
|
- - "~>"
|
|
44
45
|
- !ruby/object:Gem::Version
|
|
45
46
|
version: '2.1'
|
|
47
|
+
description:
|
|
46
48
|
email:
|
|
47
49
|
- tieeeeen1994@gmail.com
|
|
48
50
|
executables: []
|
|
@@ -63,6 +65,11 @@ files:
|
|
|
63
65
|
- lib/nueca_rails_interfaces/v1/query_interface.rb
|
|
64
66
|
- lib/nueca_rails_interfaces/v1/service_interface.rb
|
|
65
67
|
- lib/nueca_rails_interfaces/v2/form_interface.rb
|
|
68
|
+
- lib/nueca_rails_interfaces/v2/pagination/base_adapter.rb
|
|
69
|
+
- lib/nueca_rails_interfaces/v2/pagination/kaminari_adapter.rb
|
|
70
|
+
- lib/nueca_rails_interfaces/v2/pagination/pagy_adapter.rb
|
|
71
|
+
- lib/nueca_rails_interfaces/v2/pagination/will_paginate_adapter.rb
|
|
72
|
+
- lib/nueca_rails_interfaces/v2/query_interface.rb
|
|
66
73
|
- lib/nueca_rails_interfaces/v2/service_interface.rb
|
|
67
74
|
- lib/nueca_rails_interfaces/v3/form_interface.rb
|
|
68
75
|
- lib/nueca_rails_interfaces/v3/service_interface.rb
|
|
@@ -73,6 +80,7 @@ licenses:
|
|
|
73
80
|
- MIT
|
|
74
81
|
metadata:
|
|
75
82
|
rubygems_mfa_required: 'true'
|
|
83
|
+
post_install_message:
|
|
76
84
|
rdoc_options: []
|
|
77
85
|
require_paths:
|
|
78
86
|
- lib
|
|
@@ -87,7 +95,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
87
95
|
- !ruby/object:Gem::Version
|
|
88
96
|
version: '0'
|
|
89
97
|
requirements: []
|
|
90
|
-
rubygems_version:
|
|
98
|
+
rubygems_version: 3.0.3.1
|
|
99
|
+
signing_key:
|
|
91
100
|
specification_version: 4
|
|
92
101
|
summary: Interfaces for known object entities in Rails Development at Nueca.
|
|
93
102
|
test_files: []
|