forest_admin_agent 1.38.2 → 1.38.3
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/forest_admin_agent/routes/resources/list.rb +1 -1
- data/lib/forest_admin_agent/routes/resources/related/list_related.rb +1 -1
- data/lib/forest_admin_agent/routes/resources/show.rb +1 -1
- data/lib/forest_admin_agent/serializer/forest_serializer_override.rb +14 -13
- data/lib/forest_admin_agent/utils/query_string_parser.rb +59 -10
- data/lib/forest_admin_agent/utils/schema/schema_emitter.rb +1 -1
- data/lib/forest_admin_agent/version.rb +1 -1
- 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: 8240dc695f68ad1315a072be614a48151c0f52a0a35596500face2c12bdc3847
|
|
4
|
+
data.tar.gz: 267ec0985751c7c86e5df4c426862063bf1b5e41e06ba24d7ee14bf1a80ecf69
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2966283a4f8b14022cdd74a54c6e366cdfae74314cd64d77fafbb8c7c258fa860dcacafc0e1dcd842d7d590ed63884a2550aa16066696d8313d0427fa552ad3b
|
|
7
|
+
data.tar.gz: c943da4d2edf12f3e4f2b34d10ee70184befe11fe276cb246f785051cb7b7fcfb6e885459c9e5431e0351c6621db30ee6e2cab5ad93ee5c9ed3b8cf152ce63cc
|
|
@@ -43,7 +43,7 @@ module ForestAdminAgent
|
|
|
43
43
|
class_name: context.collection.name,
|
|
44
44
|
is_collection: true,
|
|
45
45
|
serializer: Serializer::ForestSerializer,
|
|
46
|
-
include: projection.
|
|
46
|
+
include: projection.relation_include_paths,
|
|
47
47
|
meta: handle_search_decorator(args[:params]['search'], records, context.collection)
|
|
48
48
|
)
|
|
49
49
|
}
|
|
@@ -54,23 +54,24 @@ module ForestAdminAgent
|
|
|
54
54
|
# Full linkage: a request for comments.author MUST automatically include comments
|
|
55
55
|
# in the response.
|
|
56
56
|
objects = is_collection ? object : [object]
|
|
57
|
+
|
|
58
|
+
relation = ForestAdminAgent::Facades::Container.datasource
|
|
59
|
+
.get_collection(options[:class_name].gsub('::', '__'))
|
|
60
|
+
.schema[:fields][attribute_name]
|
|
61
|
+
if relation.type == 'PolymorphicManyToOne'
|
|
62
|
+
relation_class_name = root_object[relation.foreign_key_type_field]
|
|
63
|
+
else
|
|
64
|
+
relation_class_name = ForestAdminAgent::Facades::Container.datasource.get_collection(relation.foreign_collection).name
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
related_collection_options = options.merge(class_name: relation_class_name)
|
|
68
|
+
|
|
57
69
|
if child_inclusion_tree[:_include] == true
|
|
58
70
|
# Include the current level objects if the _include attribute exists.
|
|
59
71
|
# If it is not set, that indicates that this is an inner path and not a leaf and will
|
|
60
72
|
# be followed by the recursion below.
|
|
61
73
|
objects.each do |obj|
|
|
62
|
-
|
|
63
|
-
.get_collection(options[:class_name].gsub('::', '__'))
|
|
64
|
-
.schema[:fields][attribute_name]
|
|
65
|
-
if relation.type == 'PolymorphicManyToOne'
|
|
66
|
-
relation_class_name = root_object[relation.foreign_key_type_field]
|
|
67
|
-
else
|
|
68
|
-
relation_class_name = ForestAdminAgent::Facades::Container.datasource.get_collection(relation.foreign_collection).name
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
option_relation = options.clone
|
|
72
|
-
option_relation[:class_name] = relation_class_name
|
|
73
|
-
obj_serializer = JSONAPI::Serializer.find_serializer(obj, option_relation)
|
|
74
|
+
obj_serializer = JSONAPI::Serializer.find_serializer(obj, related_collection_options)
|
|
74
75
|
|
|
75
76
|
# Use keys of ['posts', '1'] for the results to enforce uniqueness.
|
|
76
77
|
# Spec: A compound document MUST NOT include more than one resource object for each
|
|
@@ -105,7 +106,7 @@ module ForestAdminAgent
|
|
|
105
106
|
|
|
106
107
|
# For each object we just loaded, find all deeper recursive relationships.
|
|
107
108
|
objects.each do |obj|
|
|
108
|
-
find_recursive_relationships(obj, child_inclusion_tree, results,
|
|
109
|
+
find_recursive_relationships(obj, child_inclusion_tree, results, related_collection_options)
|
|
109
110
|
end
|
|
110
111
|
end
|
|
111
112
|
nil
|
|
@@ -9,6 +9,7 @@ module ForestAdminAgent
|
|
|
9
9
|
|
|
10
10
|
DEFAULT_ITEMS_PER_PAGE = '15'.freeze
|
|
11
11
|
DEFAULT_PAGE_TO_SKIP = '1'.freeze
|
|
12
|
+
POLYMORPHIC_TARGET_WILDCARD = '*'.freeze
|
|
12
13
|
|
|
13
14
|
def self.parse_condition_tree(collection, args)
|
|
14
15
|
filters = begin
|
|
@@ -88,7 +89,7 @@ module ForestAdminAgent
|
|
|
88
89
|
when 'Column'
|
|
89
90
|
field_name
|
|
90
91
|
when 'PolymorphicManyToOne'
|
|
91
|
-
"#{field_name}
|
|
92
|
+
"#{field_name}:#{POLYMORPHIC_TARGET_WILDCARD}"
|
|
92
93
|
else
|
|
93
94
|
relation_fields = args.dig(:params, :fields, field_name)
|
|
94
95
|
|
|
@@ -110,18 +111,63 @@ module ForestAdminAgent
|
|
|
110
111
|
root_field_names_with_types = root_field_names.dup
|
|
111
112
|
add_polymorphic_type_fields(collection, root_field_names_with_types)
|
|
112
113
|
|
|
113
|
-
projection_fields = requested_paths.map
|
|
114
|
-
field_name, nested_path = path.split(':', 2)
|
|
115
|
-
field = get_field(collection, field_name)
|
|
114
|
+
projection_fields = requested_paths.map { |path| expand_polymorphic_leaf(collection, path) }
|
|
116
115
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
projection_fields |
|
|
117
|
+
(root_field_names_with_types - root_field_names) |
|
|
118
|
+
nested_polymorphic_linkage_fields(collection, projection_fields)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def self.expand_polymorphic_leaf(collection, path)
|
|
122
|
+
segments = path.split(':')
|
|
123
|
+
leaf_index = segments.size - 1
|
|
124
|
+
|
|
125
|
+
each_field_along_path(collection, segments) do |field, index|
|
|
126
|
+
return "#{path}:#{POLYMORPHIC_TARGET_WILDCARD}" if polymorphic_many_to_one?(field) && index == leaf_index
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
path
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def self.nested_polymorphic_linkage_fields(collection, projection_fields)
|
|
133
|
+
projection_fields.flat_map do |path|
|
|
134
|
+
segments = path.split(':')
|
|
135
|
+
|
|
136
|
+
each_field_along_path(collection, segments).flat_map do |field, index|
|
|
137
|
+
next [] unless polymorphic_many_to_one?(field) && index.positive?
|
|
138
|
+
|
|
139
|
+
polymorphic_linkage_columns(field, segments[0...index])
|
|
121
140
|
end
|
|
122
141
|
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def self.polymorphic_linkage_columns(field, relation_path)
|
|
145
|
+
[field.foreign_key_type_field, field.foreign_key].map { |column| (relation_path + [column]).join(':') }
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def self.each_field_along_path(collection, segments)
|
|
149
|
+
return to_enum(:each_field_along_path, collection, segments) unless block_given?
|
|
150
|
+
|
|
151
|
+
current_collection = collection
|
|
152
|
+
|
|
153
|
+
segments.each_with_index do |segment, index|
|
|
154
|
+
field = field_along_path(current_collection, segment, root: index.zero?)
|
|
155
|
+
break if field.nil?
|
|
156
|
+
|
|
157
|
+
yield field, index
|
|
158
|
+
|
|
159
|
+
break unless field.respond_to?(:foreign_collection)
|
|
160
|
+
|
|
161
|
+
current_collection = collection.datasource.get_collection(field.foreign_collection)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def self.field_along_path(collection, segment, root:)
|
|
166
|
+
root ? get_field(collection, segment) : collection.schema[:fields][segment]
|
|
167
|
+
end
|
|
123
168
|
|
|
124
|
-
|
|
169
|
+
def self.polymorphic_many_to_one?(field)
|
|
170
|
+
field.type == 'PolymorphicManyToOne'
|
|
125
171
|
end
|
|
126
172
|
|
|
127
173
|
def self.get_field(collection, field_name)
|
|
@@ -135,7 +181,10 @@ module ForestAdminAgent
|
|
|
135
181
|
'Please check if the field name is correct.'
|
|
136
182
|
end
|
|
137
183
|
private_class_method :add_polymorphic_type_fields, :build_projection_fields,
|
|
138
|
-
:build_header_projection_fields, :get_field
|
|
184
|
+
:build_header_projection_fields, :get_field,
|
|
185
|
+
:expand_polymorphic_leaf, :nested_polymorphic_linkage_fields,
|
|
186
|
+
:polymorphic_linkage_columns, :each_field_along_path,
|
|
187
|
+
:field_along_path, :polymorphic_many_to_one?
|
|
139
188
|
|
|
140
189
|
def self.parse_projection_with_pks(collection, args)
|
|
141
190
|
parse_projection_from_request(collection, args).with_pks(collection)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: forest_admin_agent
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.38.
|
|
4
|
+
version: 1.38.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matthieu
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: exe
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2026-08-
|
|
12
|
+
date: 2026-08-14 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activesupport
|