jpie 4.1.4.pre.202611030311 → 4.1.5
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 618cb164f0b64934d5cd9a0c6e871b726bcc6b40f4add24c3204bea490a0cd5c
|
|
4
|
+
data.tar.gz: f4acc02e6f57760deae01dc2d4c49acb29fb5273acefb3eac290f7519e3f53d4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b83a3b08c429dc700144718b112c578bb9c67243a05a2400ef7fdd9055f614e50852e4819bd63c6897e04cf168eee09e1f7d2b606da39340b9dc6acd2e723b8a
|
|
7
|
+
data.tar.gz: 79f17c229521c0c99541e9787e298e9e00268996759ca8a54f67fec95f212f3cd7f124ea672d8c9da65f65546c6ad02794c971b49a8a8fef7b874883eb601760
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,32 @@ at release time.
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [4.1.5] - 2026-11-11
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Run resource preloads once for the subclasses of a polymorphic hop.** The
|
|
15
|
+
include preload step grouped the targets of a hop by exact class and ran the
|
|
16
|
+
`records` preloads of the resource once for each class. Five STI subclasses
|
|
17
|
+
that share one preload set ran each preload five times. The step now groups
|
|
18
|
+
the targets by the preloads their resource declares. Classes that share a
|
|
19
|
+
preload set run each preload once for all their records. A mixed STI set on
|
|
20
|
+
a hop that is not polymorphic now gets the preloads of every subclass. The
|
|
21
|
+
response does not change. Regression spec:
|
|
22
|
+
`polymorphic_sti_resource_preload_spec.rb`.
|
|
23
|
+
|
|
24
|
+
## [4.1.4] - 2026-11-10
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **Vet an STI include once for the base class.** The include filter vets
|
|
29
|
+
record ids under the class the association reads, the base class of an STI
|
|
30
|
+
tree. The warm step grouped the loaded records by their own subclass, so
|
|
31
|
+
the warm work was lost and the serializer ran its own query for each
|
|
32
|
+
parent. The warm step now uses the association class. An include of an STI
|
|
33
|
+
association costs one vetting query for the whole page. Regression spec:
|
|
34
|
+
`include_filter_sti_base_class_spec.rb`.
|
|
35
|
+
|
|
10
36
|
## [4.1.3] - 2026-10-10
|
|
11
37
|
|
|
12
38
|
### Fixed
|
|
@@ -66,7 +66,7 @@ module JSONAPI
|
|
|
66
66
|
targets = collect_include_targets(records, association_name)
|
|
67
67
|
next if targets.empty?
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
apply_resource_preloads(targets)
|
|
70
70
|
next if subtree.empty?
|
|
71
71
|
|
|
72
72
|
descend_resource_tree(targets, reflection, subtree)
|
|
@@ -85,11 +85,13 @@ module JSONAPI
|
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
# Groups the targets by the preloads their resource declares, so classes that share them
|
|
89
|
+
# (STI subclasses and sibling resources) run each preload once for all their records.
|
|
90
|
+
def apply_resource_preloads(targets)
|
|
91
|
+
groups = Hash.new { |hash, values| hash[values] = [] }
|
|
92
|
+
targets.group_by(&:class).each { |klass, records| groups[resource_preload_values(klass)].concat(records) }
|
|
93
|
+
groups.each do |values, records|
|
|
94
|
+
ActiveRecord::Associations::Preloader.new(records:, associations: values).call unless values.empty?
|
|
93
95
|
end
|
|
94
96
|
end
|
|
95
97
|
|
|
@@ -100,15 +102,9 @@ module JSONAPI
|
|
|
100
102
|
end.compact.uniq
|
|
101
103
|
end
|
|
102
104
|
|
|
103
|
-
def
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
klass = records.first.class
|
|
107
|
-
resource_scope = ResourceLoader.find_for_model(klass, namespace: jsonapi_namespace).records
|
|
108
|
-
preload_values = resource_scope.preload_values + resource_scope.includes_values
|
|
109
|
-
return if preload_values.empty?
|
|
110
|
-
|
|
111
|
-
ActiveRecord::Associations::Preloader.new(records:, associations: preload_values).call
|
|
105
|
+
def resource_preload_values(klass)
|
|
106
|
+
scope = ResourceLoader.find_for_model(klass, namespace: jsonapi_namespace).records
|
|
107
|
+
scope.preload_values + scope.includes_values
|
|
112
108
|
end
|
|
113
109
|
end
|
|
114
110
|
end
|
|
@@ -71,9 +71,18 @@ module JSONAPI
|
|
|
71
71
|
cache
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
+
# The serializer vets a hop under the class its association reads, which
|
|
75
|
+
# is the base class of an STI tree. Warm under that same class, so both use
|
|
76
|
+
# one key, and warm once per class so the page size does not set the
|
|
77
|
+
# query count.
|
|
74
78
|
def warm_include_level(cache, records, association_name)
|
|
75
|
-
|
|
76
|
-
targets.
|
|
79
|
+
ids_by_klass = Hash.new { |hash, klass| hash[klass] = [] }
|
|
80
|
+
targets = records.flat_map do |record|
|
|
81
|
+
found = loaded_association_targets(record, association_name)
|
|
82
|
+
ids_by_klass[record.association(association_name).klass].concat(found.filter_map(&:id)) if found.any?
|
|
83
|
+
found
|
|
84
|
+
end
|
|
85
|
+
ids_by_klass.each { |klass, ids| cache.warm(klass, ids) }
|
|
77
86
|
targets
|
|
78
87
|
end
|
|
79
88
|
|
data/lib/json_api/version.rb
CHANGED