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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71228b4dd69f45eb28f8fec8782eef94fc24bdf6bb164a707d19cfade5091ac7
4
- data.tar.gz: 33e2fce254db25935827d67ccc394aa7b54039212e97eaa7aae89d9006e4d5fd
3
+ metadata.gz: 516db7752a3c4d1e8aa48abe0967781c9f6b31a65155a18285febb30c058e823
4
+ data.tar.gz: f404aaf78564a04b4835c70928584a82f3313b013c71f1d5e28e78f3e814296c
5
5
  SHA512:
6
- metadata.gz: 4f1bb58917fe5070e9433acdc2c2b1cbc0341eb832331f399a08bc2138fc5080397326ec2755f7e9452ec4774e931842699c4a4fa9455e0ef1231a6532f2b2d9
7
- data.tar.gz: 346dbe116bab1da666e6e38b5d8a7f3863c0dcd2c97736a762fc107eaf77d879b6e9f52e5569e5ee4e4e56207b14c87b21a0cd4e4e10a2f33a34177720c682e7
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
- ## 2.0.pre.26
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
- add_association(aliased_as, fields) if resource.model._praxis_associations[aliased_as]
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Praxis
4
- VERSION = '2.0.pre.27'
4
+ VERSION = '2.0.pre.28'
5
5
  end
@@ -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.27
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: 2022-12-21 00:00:00.000000000 Z
12
+ date: 2023-01-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport