active_record-cursor_paginator 0.3.1 → 0.3.2
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/CHANGELOG.md +5 -0
- data/README.md +12 -0
- data/lib/active_record/cursor_paginator/version.rb +1 -1
- data/lib/active_record/cursor_paginator.rb +33 -3
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2b976c754e305df50a8c5eb4889bf98a6041a3e4c8fa73b7c6d6a4566068037a
|
|
4
|
+
data.tar.gz: 680ed7b82dd56e0c1a72db977350b701bdd9c90666053e7399f9dd9d280afae6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7097e691c6a902bb42d0c2b8a7cb55a22d768b3d7bedefe344d05500efa6e665145d5e6ed8263bc3cbc313dd256bfab294a2651aa6fc1b230c910a8bdabd7abb
|
|
7
|
+
data.tar.gz: e1508a1aed8100c86f8f389a16b35996a4d633fb371a0e7a918ab728ee7e236f57b22df4d9d7ab6a1b8fe9785294bd0c5cc804f2f6d0e712d2ef4e88b746de84
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## [0.3.2] - 2026-06-03
|
|
2
|
+
|
|
3
|
+
- Fix timezone offset in datetime cursor values being ignored in WHERE clause
|
|
4
|
+
- Warn when a datetime cursor column is a join table alias, as type inference may be inaccurate
|
|
5
|
+
|
|
1
6
|
## [0.3.1] - 2026-03-06
|
|
2
7
|
|
|
3
8
|
- Add support for Rails enum columns
|
data/README.md
CHANGED
|
@@ -65,6 +65,18 @@ ActiveSupport::JSON::Encoding.time_precision = 6
|
|
|
65
65
|
|
|
66
66
|
## Limitation
|
|
67
67
|
|
|
68
|
+
### Datetime cursor values on join table columns
|
|
69
|
+
|
|
70
|
+
When ordering by a datetime column from a joined table via an alias (e.g. `authors.created_at as author_created_at`), the column type is inferred from the root model. If the joined table's column type differs from the root model's column with the same name, timezone conversion in cursor values may be inaccurate.
|
|
71
|
+
|
|
72
|
+
A warning is logged when this situation is detected:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
[CursorPaginator] Cursor column 'author_created_at' resolves to 'authors.created_at'
|
|
76
|
+
(join column). Type is inferred from Post and may be inaccurate.
|
|
77
|
+
Timezone-aware datetime cursors on joined tables may not work correctly.
|
|
78
|
+
```
|
|
79
|
+
|
|
68
80
|
This library does not support the following order expressions
|
|
69
81
|
|
|
70
82
|
```ruby
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'active_record'
|
|
4
|
+
require 'set'
|
|
4
5
|
require_relative 'cursor_paginator/version'
|
|
5
6
|
|
|
6
7
|
module ActiveRecord
|
|
@@ -168,7 +169,7 @@ module ActiveRecord
|
|
|
168
169
|
def cursor_for_record(record)
|
|
169
170
|
unencoded_cursor = @fields.map do |field|
|
|
170
171
|
field_name = field.keys.first
|
|
171
|
-
value = if record.class.defined_enums.
|
|
172
|
+
value = if record.class.defined_enums.has_key?(field_name.to_s)
|
|
172
173
|
# For enum columns, get the raw integer value from the database
|
|
173
174
|
record.read_attribute_before_type_cast(field_name)
|
|
174
175
|
else
|
|
@@ -268,14 +269,43 @@ module ActiveRecord
|
|
|
268
269
|
def build_filter_query(sorted_relation, op, current_field, prev_fields)
|
|
269
270
|
relation = sorted_relation
|
|
270
271
|
prev_fields.each do |col, val|
|
|
272
|
+
col_key = col
|
|
271
273
|
col = @aliases[col] if @aliases.has_key? col
|
|
272
274
|
col = qualify_field_if_needed(col)
|
|
273
|
-
relation = relation.where("#{col} = ?", val)
|
|
275
|
+
relation = relation.where("#{col} = ?", cast_cursor_value(col_key, val))
|
|
274
276
|
end
|
|
275
277
|
col, val = current_field
|
|
278
|
+
col_key = col
|
|
276
279
|
col = @aliases[col] if @aliases.has_key? col
|
|
277
280
|
col = qualify_field_if_needed(col)
|
|
278
|
-
relation.where("#{col} #{op} ?", val)
|
|
281
|
+
relation.where("#{col} #{op} ?", cast_cursor_value(col_key, val))
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def cast_cursor_value(col_name, val)
|
|
285
|
+
return val unless val.is_a?(String)
|
|
286
|
+
|
|
287
|
+
resolved_expr = @aliases[col_name.to_s]
|
|
288
|
+
resolved_col = (resolved_expr || col_name.to_s).split('.').last
|
|
289
|
+
type = @relation.klass.type_for_attribute(resolved_col)
|
|
290
|
+
|
|
291
|
+
return val unless %i[datetime time timestamp].include?(type.type)
|
|
292
|
+
|
|
293
|
+
warn_join_column_cast(col_name, resolved_expr) if resolved_expr&.match?(/\A\w+\.\w+\z/)
|
|
294
|
+
|
|
295
|
+
type.cast(val)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def warn_join_column_cast(alias_name, expression)
|
|
299
|
+
@_warned_join_casts ||= Set.new
|
|
300
|
+
return if @_warned_join_casts.include?(alias_name)
|
|
301
|
+
|
|
302
|
+
@_warned_join_casts << alias_name
|
|
303
|
+
|
|
304
|
+
msg = "[CursorPaginator] Cursor column '#{alias_name}' resolves to '#{expression}' " \
|
|
305
|
+
"(join column). Type is inferred from #{@relation.klass.name} and may be " \
|
|
306
|
+
'inaccurate. Timezone-aware datetime cursors on joined tables may not work correctly.'
|
|
307
|
+
logger = ActiveRecord::Base.logger
|
|
308
|
+
logger ? logger.warn(msg) : Kernel.warn(msg)
|
|
279
309
|
end
|
|
280
310
|
|
|
281
311
|
# parse aliases from select values
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_record-cursor_paginator
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shinichi Sugiyama
|
|
@@ -66,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
67
|
version: '0'
|
|
68
68
|
requirements: []
|
|
69
|
-
rubygems_version: 3.7
|
|
69
|
+
rubygems_version: 3.6.7
|
|
70
70
|
specification_version: 4
|
|
71
71
|
summary: cursor pagination for ActiveRecord
|
|
72
72
|
test_files: []
|