serega 0.37.1 → 0.37.2

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: ca01b1c5668c5ce5963e5f2b71540dae1d023eed44c6e9e026d43e63fcead4c6
4
- data.tar.gz: f526d737921efe1789751b51ff15b503b0febe2d5aafbb1a57666625a14b2228
3
+ metadata.gz: fe536c6d684f24508a5153d1fc679cd451d2360ab3d752ff2ba08a2249b264c9
4
+ data.tar.gz: 0110de5fca4df251b1101daaba232bf1fcace80b6290bb95e35a8c892fc1ce1b
5
5
  SHA512:
6
- metadata.gz: 643c12f65a16dbce5d05a8262df0f85fc6a5055436a65d2590f0615ccba5a9cb2d1287d4ec1262b9d0f252432262e88799b55d13ca7ce5fed252c58faf9b7a1a
7
- data.tar.gz: fa8ad847f04617c8ea70cf227aca9bf9ede02c1b1449afb6547b821f09cd8a27638cb5d8904ddc576dfe12c01d5cd6991a99e7cb9fa1cf28d46d2053c7650978
6
+ metadata.gz: 5a7f60a35e6791337f15772efeb2dfa0363ff96bb99f815c849c1fb5b40125854802b39ef492bea078f6bb614171b29b8f0e5409e421c52e6f24bf39eabfffdd
7
+ data.tar.gz: 2d3adb93d754ed3fb42581e5a45493e30e3f1fbb1cda8c68956e5cc047be42417f8cd487074cae5ce11fe72dbfa633ba32ccdc52dd002de17f349b7532c10f4f
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.37.1
1
+ 0.37.2
@@ -9,10 +9,6 @@ class Serega
9
9
  # AttributeNormalizer instance methods
10
10
  #
11
11
  module AttributeNormalizerInstanceMethods
12
- # Identity loader that routes relation/preload attributes through the batch
13
- # mechanism. Its result is never read — the attribute's value block still
14
- # computes the value.
15
- AUTO_BATCH_LOADER = proc { |records| records.to_h { |record| [record, record] } }
16
12
  # Attribute initial params
17
13
  # @return [Hash] Attribute initial params
18
14
  attr_reader :init_name, :init_opts, :init_block
@@ -152,13 +148,24 @@ class Serega
152
148
 
153
149
  hide_setting = config.hide_by_default
154
150
  return true if hide_setting == true
155
- return true if hide_setting == :auto && (preloads || init_opts.key?(:batch))
151
+ return true if hide_setting == :auto && preload_or_batch?
156
152
 
157
153
  # Return nil for undefined value which means "not hide" but allows
158
154
  # to change this value by plugins
159
155
  nil
160
156
  end
161
157
 
158
+ # The `hide_by_default = :auto` criterion: hide attributes that fetch extra
159
+ # data on demand — those declared with `:preload` or an explicit `:batch`.
160
+ #
161
+ # This is intentionally narrower than a "goes through the batch mechanism"
162
+ # check (`SeregaPlanPoint#batch?`): a plain relation (`serializer:` without
163
+ # `:preload`) is batch-processed too, but it only serializes an already-loaded
164
+ # nested object, so it stays visible by default.
165
+ def preload_or_batch?
166
+ !!(preloads || init_opts.key?(:batch))
167
+ end
168
+
162
169
  def config
163
170
  self.class.serializer_class.config
164
171
  end
@@ -197,9 +204,11 @@ class Serega
197
204
  return explicit_batch_loaders(batch_opt) if batch_opt
198
205
  return FROZEN_EMPTY_ARRAY unless serializer || preloads
199
206
 
200
- loader_name = :"__auto_batch_#{name}__"
201
- self.class.serializer_class.batch(loader_name, AUTO_BATCH_LOADER)
202
- [loader_name]
207
+ # Relations and preloads only need to be routed through the batch phase
208
+ # (so objects are gathered per level and preloads run) — there is nothing
209
+ # to load, since the value comes from the attribute's own resolver. Mark
210
+ # them with the reserved marker; the batch machinery skips it.
211
+ [SeregaBatch::AUTO_BATCH_LOADER_NAME]
203
212
  end
204
213
 
205
214
  def explicit_batch_loaders(batch_opt)
@@ -41,7 +41,7 @@ class Serega
41
41
 
42
42
  handler.call(level.objects, preloads)
43
43
  rescue => error
44
- reraise_with_serialized_attribute_details(error)
44
+ SeregaUtils::SerializedAttributeError.call(error, point)
45
45
  end
46
46
 
47
47
  # Loads a single named batch for this level's objects. Caching across
@@ -51,16 +51,20 @@ class Serega
51
51
  def load_batch(loader)
52
52
  level.load(loader)
53
53
  rescue => error
54
- reraise_with_serialized_attribute_details(error)
54
+ SeregaUtils::SerializedAttributeError.call(error, point)
55
55
  end
56
56
 
57
57
  # Attaches already loaded batch values to every stored object.
58
+ # Value resolution happens here (inside the attacher), so errors are
59
+ # annotated with the attribute, matching the synchronous walk.
58
60
  # @param batches [Hash] Loaded values grouped by batch loader name
59
61
  # @return [void]
60
62
  def attach(batches)
61
63
  serialized_object_attachers.each do |object, attacher|
62
64
  attacher.call(object, batches)
63
65
  end
66
+ rescue => error
67
+ SeregaUtils::SerializedAttributeError.call(error, point)
64
68
  end
65
69
 
66
70
  attr_reader :point
@@ -68,13 +72,6 @@ class Serega
68
72
 
69
73
  private
70
74
 
71
- def reraise_with_serialized_attribute_details(error)
72
- raise error.exception(<<~MESSAGE.strip)
73
- #{error.message}
74
- (when serializing '#{point.name}' attribute in #{point.class.serializer_class})
75
- MESSAGE
76
- end
77
-
78
75
  attr_reader :serialized_object_attachers
79
76
  end
80
77
 
@@ -5,6 +5,11 @@ class Serega
5
5
  # Batch feature main module
6
6
  #
7
7
  module SeregaBatch
8
+ # Reserved batch-loader name that marks relation/preload attributes as
9
+ # batch-processed. It has no registered loader — the attribute's value comes
10
+ # from its own resolver — so `load_batches` skips it (nothing to load).
11
+ AUTO_BATCH_LOADER_NAME = :__auto_batch__
12
+
8
13
  #
9
14
  # Batch loaders
10
15
  #
@@ -98,6 +103,10 @@ class Serega
98
103
 
99
104
  batches = {}
100
105
  point.batch_loaders.each do |batch_loader_name|
106
+ # Auto-batched relations/preloads carry the marker, not a real loader:
107
+ # their value comes from their own resolver, so there is nothing to load.
108
+ next if batch_loader_name == AUTO_BATCH_LOADER_NAME
109
+
101
110
  loader = serializer_class.batch_loaders[batch_loader_name]
102
111
  batches[batch_loader_name] = attribute_loader.load_batch(loader)
103
112
  end
@@ -55,7 +55,7 @@ class Serega
55
55
  plan.points.each_with_object({}) do |point, container|
56
56
  serialize_point(object, point, container)
57
57
  rescue => error
58
- reraise_with_serialized_attribute_details(error, point)
58
+ SeregaUtils::SerializedAttributeError.call(error, point)
59
59
  end
60
60
  end
61
61
 
@@ -103,13 +103,6 @@ class Serega
103
103
  def array?(object, many)
104
104
  many.nil? ? object.is_a?(Enumerable) : many
105
105
  end
106
-
107
- def reraise_with_serialized_attribute_details(error, point)
108
- raise error.exception(<<~MESSAGE.strip)
109
- #{error.message}
110
- (when serializing '#{point.name}' attribute in #{self.class.serializer_class})
111
- MESSAGE
112
- end
113
106
  end
114
107
 
115
108
  extend Serega::SeregaHelpers::SerializerClassHelper
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module SeregaUtils
5
+ #
6
+ # Reraises an error, adding which attribute and serializer were being
7
+ # serialized when it happened. Shared by the synchronous serialization walk
8
+ # and the batch attach phase so the message stays identical for every
9
+ # attribute, whether its value is resolved inline or during batch loading.
10
+ #
11
+ module SerializedAttributeError
12
+ module_function
13
+
14
+ #
15
+ # @param error [Exception] Original error
16
+ # @param point [SeregaPlanPoint] Plan point being serialized
17
+ #
18
+ # @return [void]
19
+ #
20
+ def call(error, point)
21
+ raise error.exception(<<~MESSAGE.strip)
22
+ #{error.message}
23
+ (when serializing '#{point.name}' attribute in #{point.class.serializer_class})
24
+ MESSAGE
25
+ end
26
+ end
27
+ end
28
+ end
data/lib/serega.rb CHANGED
@@ -22,6 +22,7 @@ require_relative "serega/helpers/serializer_class_helper"
22
22
  require_relative "serega/utils/enum_deep_dup"
23
23
  require_relative "serega/utils/enum_deep_freeze"
24
24
  require_relative "serega/utils/method_signature"
25
+ require_relative "serega/utils/serialized_attribute_error"
25
26
  require_relative "serega/utils/symbol_name"
26
27
  require_relative "serega/utils/to_hash"
27
28
  require_relative "serega/attribute_value_resolvers/batch"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serega
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.37.1
4
+ version: 0.37.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Glushkov
@@ -74,6 +74,7 @@ files:
74
74
  - lib/serega/utils/enum_deep_dup.rb
75
75
  - lib/serega/utils/enum_deep_freeze.rb
76
76
  - lib/serega/utils/method_signature.rb
77
+ - lib/serega/utils/serialized_attribute_error.rb
77
78
  - lib/serega/utils/symbol_name.rb
78
79
  - lib/serega/utils/to_hash.rb
79
80
  - lib/serega/validations/attribute/check_block.rb