active_mappers 1.5.3 → 1.6.0

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: 231960e865a55f8f5326db64a3c27483074667ceadd949b7c5f92db45b9ba84c
4
- data.tar.gz: 440609845994bf984c26bea417b0188f68ebd115e23188e0582bf97cdeafc488
3
+ metadata.gz: 43a75d246a1c97b9e8c31781bedf8e7893c58868b6dab6dce13aebf508d6b6a8
4
+ data.tar.gz: 569ee97b2c0db9f631012c7572e338df69795e86e0e7a5868b7867f7112ac38e
5
5
  SHA512:
6
- metadata.gz: e0e40eb769230d7aef3712c760563148acde4f9a9e3f002225ffb6415562e36c84748a26a27649b6ac67b867b99d14f8ab1a090cd87ddcb763b29dc4c635bd90
7
- data.tar.gz: 8a6dbf0fc2b7210c5cb9292420a3ec3c4d00bf666ef691f345a0423f030609b3e177ff97983bc7469500a7f1e72088bde0c7cd31e6408279e88256a4489e1ac1
6
+ metadata.gz: 22132e79ffeb517b0e163148972248bb4524e79d5e4a6827e0d91057410f7a463856613aff6a2932196a3ef09276c27aed963af6f0dcf428d4a2fb49560dc0da
7
+ data.tar.gz: eda34e0f9ec6a58a473abbfcfc9c4fcdc22f58b7b371327d56eabff76dd9c198600cc6e386b9b776f073a6358b621f68a71cc1cc77d62be218409580dd610a6d
data/README.md CHANGED
@@ -316,6 +316,34 @@ end
316
316
  RewardMapper.with(reward, context: user)
317
317
  ```
318
318
 
319
+ The context is **propagated to nested mappers**, both through `relation` and through
320
+ `polymorphic`. A child mapper rendered as a relation therefore sees the same context as
321
+ its parent, without having to walk back up the association:
322
+
323
+ ```ruby
324
+ class TicketMapper < ActiveMappers::Base
325
+ relation :pictures, PictureMapper
326
+ end
327
+
328
+ class PictureMapper < ActiveMappers::Base
329
+ each do |picture, context|
330
+ { uri: picture.uri_for(context[:app]) } # => 'scan_reduc'
331
+ end
332
+ end
333
+
334
+ TicketMapper.with(ticket, context: { app: 'scan_reduc' })
335
+ ```
336
+
337
+ A context declared on the relation itself wins over the parent's — the parent's is only a
338
+ default:
339
+
340
+ ```ruby
341
+ relation :pictures, PictureMapper, context: { app: 'always_this_one' }
342
+ ```
343
+
344
+ > Before 1.6.0, `relation` did not forward the context (`polymorphic` already did), so a
345
+ > nested mapper always received `nil`.
346
+
319
347
  ### Scope
320
348
 
321
349
  ActiveMappers does not yet support inheritance. However we provide an even better alternative named `scope`.
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'active_mappers'
3
- s.version = '1.5.3'
4
- s.date = '2026-01-30'
3
+ s.version = '1.6.0'
4
+ s.date = '2026-09-25'
5
5
  s.summary = 'Slick, fast view layer for you Rails API.'
6
6
  s.description = 'Fast, simple, declarative way to design your API\'s view layer'
7
7
  s.authors = ['Michaël Villeneuve', 'Loïc SENCE']
@@ -3,6 +3,11 @@ require 'ruby2ruby'
3
3
  require 'ruby_parser'
4
4
 
5
5
  require 'active_support'
6
+ # ⚠️ `blank?` / `present?` sont utilisés par `with` : dans une application Rails ils
7
+ # arrivent par le require complet d'ActiveSupport, mais en test ISOLÉ la gem ne charge que
8
+ # ce qu'elle déclare — sans cette ligne, toute la suite tombait en
9
+ # `NoMethodError: undefined method 'present?'`.
10
+ require 'active_support/core_ext/object/blank'
6
11
  require 'active_support/core_ext/object/try'
7
12
  require 'active_support/core_ext/hash/except'
8
13
  require 'active_support/core_ext/string/inflections'
@@ -46,9 +51,21 @@ module ActiveMappers
46
51
  end
47
52
  end
48
53
 
54
+ # ⚠️ Le bloc capture `context` et le passe au mapper enfant. Sans ça, un mapper rendu
55
+ # comme relation recevait toujours `nil` — alors que `polymorphic` le propageait déjà :
56
+ # l'enfant ne pouvait donc pas savoir pour qui on rendait (app appelante, scope…), et
57
+ # la seule parade était de remonter au parent par l'association.
58
+ #
59
+ # ⚠️ Le contexte est ajouté SOUS `options`, pas par-dessus : un `context:` passé
60
+ # explicitement à la déclaration (`relation :x, Mapper, context: {...}`) reste
61
+ # prioritaire, et celui du parent ne sert que de défaut.
62
+ #
63
+ # ⚠️ On MERGE au lieu d'écrire `options[:context] = context` : `options` est capturé par
64
+ # la closure et partagé par TOUS les rendus de ce mapper. Le muter ferait fuiter le
65
+ # contexte d'un rendu à l'autre entre threads.
49
66
  def self.relation(key, mapper = nil, **options)
50
67
  path = options[:optional_path] || key
51
- each do |resource|
68
+ each do |resource, context|
52
69
  mapper_to_use = if mapper
53
70
  mapper
54
71
  else
@@ -59,16 +76,17 @@ module ActiveMappers
59
76
 
60
77
  raise "'#{mapper_to_use.name}' should be a mapper" unless mapper_to_use.ancestors.map(&:to_s).include?("ActiveMappers::Base")
61
78
 
62
- { key => mapper_to_use.with(path.to_s.split('.').inject(resource, :try), default_options.merge(options)) }
79
+ { key => mapper_to_use.with(path.to_s.split('.').inject(resource, :try), { context: context }.merge(default_options.merge(options))) }
63
80
  end
64
81
  end
65
82
 
66
83
  def self.polymorphic(key, **options)
67
84
  each do |resource, context|
68
- options[:context] = context
85
+ # Même merge non mutant que `relation` : `options[:context] = context` mutait le
86
+ # hash capturé par la closure, partagé par tous les rendus de ce mapper.
69
87
  if polymorphic_resource = resource.send("#{key}_type")
70
88
  resource_mapper = "#{KeyTransformer.base_namespace(self)}::#{polymorphic_resource}Mapper".constantize
71
- { key => resource_mapper.with(resource.send(key), default_options.merge(options)) }
89
+ { key => resource_mapper.with(resource.send(key), { context: context }.merge(default_options.merge(options))) }
72
90
  else
73
91
  {}
74
92
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_mappers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michaël Villeneuve
8
8
  - Loïc SENCE
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-01-30 00:00:00.000000000 Z
11
+ date: 2026-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
117
  requirements: []
118
- rubygems_version: 4.0.3
118
+ rubygems_version: 4.0.6
119
119
  specification_version: 4
120
120
  summary: Slick, fast view layer for you Rails API.
121
121
  test_files: []