praxis 2.0.pre.27 → 2.0.pre.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -2
- data/lib/praxis/mapper/selector_generator.rb +18 -1
- data/lib/praxis/version.rb +1 -1
- data/spec/praxis/mapper/selector_generator_spec.rb +49 -0
- data/spec/support/spec_resources.rb +3 -0
- 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: 516db7752a3c4d1e8aa48abe0967781c9f6b31a65155a18285febb30c058e823
|
4
|
+
data.tar.gz: f404aaf78564a04b4835c70928584a82f3313b013c71f1d5e28e78f3e814296c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b1eae94ededb45b3cd48fdfe2440c5ac41af66b5c251e3a682906709d67a15d02d7463c7dc2e384fb4c217a745b7cec438b0d919e614f5f4c4c499a94cb17a4
|
7
|
+
data.tar.gz: fe8c7d881560b09702a4fe63680046f472efebb18aa1c09b01138b6dd9569727d29759bfc0e765095d52ec92df1c136e1de1419bf3fe282cc0b56e92cb3b1c9e
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# Praxis Changelog
|
2
2
|
|
3
3
|
## next
|
4
|
-
|
5
|
-
|
4
|
+
## 2.0.pre.28
|
5
|
+
* Enhance the mapper's Resource property to allow for a couple more powerful options using the `as:` keyword:
|
6
|
+
* `as: :self` will provide a way to map any further incoming fields on top of the already existing object. This is useful when we want to expose some properties for a resource, grouped within a sub structure, but that in reality they exist directly in the resource's underlying model (i.e., to organize the information of the model in a more structured/groupable way).
|
7
|
+
* `as: 'association1.association2'` allows us to traverse more than 1 association, and continue applying the incoming fields under that. This is commonly used when we want to expose a relationship on a resource, which is really coming from more than a single association level depth.
|
8
|
+
## 2.0.pre.27
|
6
9
|
* Introduce a new `as:` option for resource's `property`, to indicate that the underlying association method it is connected to, has a different name.
|
7
10
|
* This also will create a delegation function for the property name, that instead of calling the underlying association on the record, and wrapping the result with a resource instance, it will simply call the aliased method name (which is likely gonna hit the autogenerated code for that properyty, unless we have overriden it)
|
8
11
|
* With this change, the selector generator (i.e., the thing that looks at the incoming `fields` parameters and calculates which select and includes are necessary to query all the data we need), will be able to understand this aliasing cases, and properly pass along, and continue expanding any nested fields that are under the property name (before this, and further inner fields would be not included as soon as we hit a property that didn't have that direct association underneath).
|
@@ -68,7 +68,24 @@ module Praxis
|
|
68
68
|
# Always add the underlying association if we're overriding the name...
|
69
69
|
if (praxis_compat_model = resource.model&.respond_to?(:_praxis_associations))
|
70
70
|
aliased_as = resource.properties[name][:as]
|
71
|
-
|
71
|
+
if aliased_as == :self
|
72
|
+
# Special keyword to add itself as the association, but still continue procesing the fields
|
73
|
+
# This is useful when we expose resource fields tucked inside another sub-struct, this way
|
74
|
+
# we can make sure that if the fields necessary to compute things inside the struct, they are preloaded
|
75
|
+
add(fields)
|
76
|
+
else
|
77
|
+
first, *rest = aliased_as.to_s.split('.').map(&:to_sym)
|
78
|
+
|
79
|
+
extended_fields = \
|
80
|
+
if rest.empty?
|
81
|
+
fields
|
82
|
+
else
|
83
|
+
rest.reverse.inject(fields) do |accum, prop|
|
84
|
+
{ prop => accum }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
add_association(first, extended_fields) if resource.model._praxis_associations[first]
|
88
|
+
end
|
72
89
|
end
|
73
90
|
dependencies&.each do |dependency|
|
74
91
|
# To detect recursion, let's allow mapping depending fields to the same name of the property
|
data/lib/praxis/version.rb
CHANGED
@@ -236,6 +236,55 @@ describe Praxis::Mapper::SelectorGenerator do
|
|
236
236
|
end
|
237
237
|
it_behaves_like 'a proper selector'
|
238
238
|
end
|
239
|
+
context 'Deep aliased underlying associations also follows any nested fields at the end of the chain...' do
|
240
|
+
let(:fields) do
|
241
|
+
{
|
242
|
+
parent_id: true,
|
243
|
+
deep_aliased_association: {
|
244
|
+
name: true
|
245
|
+
}
|
246
|
+
}
|
247
|
+
end
|
248
|
+
let(:selectors) do
|
249
|
+
{
|
250
|
+
model: SimpleModel,
|
251
|
+
columns: %i[parent_id simple_name], # No added_column, as it does not follow the dotted reference as properties, just associations
|
252
|
+
tracks: {
|
253
|
+
parent: {
|
254
|
+
model: ParentModel,
|
255
|
+
columns: %i[id],
|
256
|
+
tracks: {
|
257
|
+
simple_children: {
|
258
|
+
model: SimpleModel,
|
259
|
+
columns: %i[parent_id simple_name]
|
260
|
+
}
|
261
|
+
}
|
262
|
+
}
|
263
|
+
}
|
264
|
+
}
|
265
|
+
end
|
266
|
+
it_behaves_like 'a proper selector'
|
267
|
+
end
|
268
|
+
context 'Using self for the underlying association: follows any nested fields skipping the association name and still applies dependencies' do
|
269
|
+
let(:fields) do
|
270
|
+
{
|
271
|
+
parent_id: true,
|
272
|
+
sub_struct: {
|
273
|
+
display_name: true
|
274
|
+
}
|
275
|
+
}
|
276
|
+
end
|
277
|
+
let(:selectors) do
|
278
|
+
{
|
279
|
+
model: SimpleModel,
|
280
|
+
# Parent_id is because we asked for it at the top
|
281
|
+
# display_name because we asked for it under sub_struct, but it is marked as :self
|
282
|
+
# alway_necessary_attribute because it is a dependency of sub_struct
|
283
|
+
columns: %i[parent_id display_name alway_necessary_attribute]
|
284
|
+
}
|
285
|
+
end
|
286
|
+
it_behaves_like 'a proper selector'
|
287
|
+
end
|
239
288
|
end
|
240
289
|
|
241
290
|
context 'string associations' do
|
@@ -154,6 +154,9 @@ class SimpleResource < BaseResource
|
|
154
154
|
property :deep_nested_deps, dependencies: ['parent.simple_children.other_model.parent.display_name']
|
155
155
|
property :aliased_association, as: :other_model, dependencies: [:name]
|
156
156
|
property :overriden_aliased_association, as: :other_model, dependencies: [:name]
|
157
|
+
property :deep_aliased_association, as: 'parent.simple_children' , dependencies: [:name]
|
158
|
+
|
159
|
+
property :sub_struct, as: :self, dependencies: [:alway_necessary_attribute]
|
157
160
|
|
158
161
|
before(:update!, :do_before_update)
|
159
162
|
around(:update!, :do_around_update_nested)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: praxis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.pre.
|
4
|
+
version: 2.0.pre.28
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josep M. Blanquer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-01-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|