serega 0.6.1 → 0.7.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/serega/attribute.rb +2 -2
  4. data/lib/serega/config.rb +23 -1
  5. data/lib/serega/errors.rb +8 -5
  6. data/lib/serega/helpers/serializer_class_helper.rb +5 -0
  7. data/lib/serega/json/adapter.rb +6 -0
  8. data/lib/serega/json/json.rb +20 -0
  9. data/lib/serega/json/oj.rb +20 -0
  10. data/lib/serega/map.rb +17 -0
  11. data/lib/serega/map_point.rb +36 -1
  12. data/lib/serega/object_serializer.rb +17 -4
  13. data/lib/serega/plugins/activerecord_preloads/activerecord_preloads.rb +66 -18
  14. data/lib/serega/plugins/activerecord_preloads/lib/preloader.rb +100 -40
  15. data/lib/serega/plugins/batch/batch.rb +136 -10
  16. data/lib/serega/plugins/batch/lib/loader.rb +33 -1
  17. data/lib/serega/plugins/batch/lib/loaders.rb +15 -2
  18. data/lib/serega/plugins/batch/lib/plugins_extensions.rb +23 -1
  19. data/lib/serega/plugins/batch/lib/validations/check_batch_opt_key.rb +12 -0
  20. data/lib/serega/plugins/batch/lib/validations/check_batch_opt_loader.rb +12 -0
  21. data/lib/serega/plugins/batch/lib/validations/check_opt_batch.rb +12 -0
  22. data/lib/serega/plugins/context_metadata/context_metadata.rb +95 -13
  23. data/lib/serega/plugins/formatters/formatters.rb +94 -8
  24. data/lib/serega/plugins/hide_nil/hide_nil.rb +33 -7
  25. data/lib/serega/plugins/metadata/metadata.rb +108 -35
  26. data/lib/serega/plugins/metadata/validations/check_block.rb +3 -0
  27. data/lib/serega/plugins/metadata/validations/check_opt_hide_empty.rb +4 -1
  28. data/lib/serega/plugins/metadata/validations/check_opt_hide_nil.rb +4 -1
  29. data/lib/serega/plugins/metadata/validations/check_opts.rb +3 -0
  30. data/lib/serega/plugins/metadata/validations/check_path.rb +3 -0
  31. data/lib/serega/plugins/preloads/lib/enum_deep_freeze.rb +10 -1
  32. data/lib/serega/plugins/preloads/lib/format_user_preloads.rb +13 -4
  33. data/lib/serega/plugins/preloads/lib/main_preload_path.rb +16 -3
  34. data/lib/serega/plugins/preloads/lib/preloads_constructor.rb +4 -6
  35. data/lib/serega/plugins/preloads/preloads.rb +145 -12
  36. data/lib/serega/plugins/preloads/validations/check_opt_preload.rb +11 -0
  37. data/lib/serega/plugins/preloads/validations/check_opt_preload_path.rb +12 -0
  38. data/lib/serega/plugins/presenter/presenter.rb +20 -11
  39. data/lib/serega/plugins/root/root.rb +131 -19
  40. data/lib/serega/plugins/string_modifiers/parse_string_modifiers.rb +42 -12
  41. data/lib/serega/plugins/string_modifiers/string_modifiers.rb +14 -0
  42. data/lib/serega/plugins.rb +7 -1
  43. data/lib/serega/utils/enum_deep_dup.rb +5 -0
  44. data/lib/serega/utils/to_hash.rb +21 -3
  45. data/lib/serega/validations/attribute/check_block.rb +7 -2
  46. data/lib/serega/validations/attribute/check_name.rb +6 -0
  47. data/lib/serega/validations/attribute/check_opt_const.rb +12 -9
  48. data/lib/serega/validations/attribute/check_opt_delegate.rb +13 -10
  49. data/lib/serega/validations/attribute/check_opt_hide.rb +3 -0
  50. data/lib/serega/validations/attribute/check_opt_key.rb +12 -9
  51. data/lib/serega/validations/attribute/check_opt_many.rb +3 -0
  52. data/lib/serega/validations/attribute/check_opt_serializer.rb +3 -0
  53. data/lib/serega/validations/attribute/check_opt_value.rb +12 -9
  54. data/lib/serega/validations/check_attribute_params.rb +29 -1
  55. data/lib/serega/validations/check_initiate_params.rb +17 -0
  56. data/lib/serega/validations/check_serialize_params.rb +16 -0
  57. data/lib/serega/validations/initiate/check_modifiers.rb +15 -0
  58. data/lib/serega/validations/utils/check_allowed_keys.rb +14 -0
  59. data/lib/serega/validations/utils/check_opt_is_bool.rb +11 -0
  60. data/lib/serega/validations/utils/check_opt_is_hash.rb +11 -0
  61. data/lib/serega/validations/utils/check_opt_is_string_or_symbol.rb +11 -0
  62. data/lib/serega/version.rb +4 -0
  63. data/lib/serega.rb +83 -24
  64. metadata +2 -3
  65. data/lib/serega/serializer.rb +0 -32
@@ -3,8 +3,16 @@
3
3
  class Serega
4
4
  module SeregaPlugins
5
5
  module ActiverecordPreloads
6
+ # Handles preloads for different types of initial records
6
7
  class Preloader
7
- module ClassMethods
8
+ class << self
9
+ # Preloads associations to records
10
+ #
11
+ # @param object [Object] record(s)
12
+ # @param preloads [Hash] associations names
13
+ #
14
+ # @return [Object] provided object with preloaded associations
15
+ #
8
16
  def preload(object, preloads)
9
17
  return object if object.nil? || (object.is_a?(Array) && object.empty?) || preloads.empty?
10
18
 
@@ -14,6 +22,7 @@ class Serega
14
22
  preload_handler.preload(object, preloads)
15
23
  end
16
24
 
25
+ # @return [Array] Registered preload adapters for different types of initial records
17
26
  def handlers
18
27
  @handlers ||= [
19
28
  ActiverecordRelation,
@@ -23,12 +32,19 @@ class Serega
23
32
  ].freeze
24
33
  end
25
34
  end
26
-
27
- extend ClassMethods
28
35
  end
29
36
 
37
+ # Associations loader for prepared records
30
38
  class Loader
31
39
  # :nocov: We can check only one version of activerecord
40
+
41
+ # Preloads associations to records
42
+ #
43
+ # @param records [Array<ActiveRecord::Base>] records
44
+ # @param associations [Hash] associations names
45
+ #
46
+ # @return [void]
47
+ #
32
48
  def self.call(records, associations)
33
49
  if ActiveRecord::VERSION::MAJOR >= 7
34
50
  ActiveRecord::Associations::Preloader.new(records: records, associations: associations).call
@@ -39,75 +55,119 @@ class Serega
39
55
  # :nocov:
40
56
  end
41
57
 
58
+ # Preloader adapter for ActiveRecord object
42
59
  class ActiverecordObject
43
- module ClassMethods
60
+ class << self
61
+ #
62
+ # Checks object is kind of ActiveRecord::Base
63
+ #
64
+ # @param object [Object] object
65
+ #
66
+ # @return [Boolean] whether object is kind of ActiveRecord::Base
44
67
  def fit?(object)
45
68
  object.is_a?(ActiveRecord::Base)
46
69
  end
47
70
 
48
- def preload(object, preloads)
49
- Loader.call([object], preloads)
50
- object
71
+ #
72
+ # Preloads associations to ActiveRecord::Base record
73
+ #
74
+ # @param record [ActiveRecord::Base] record
75
+ #
76
+ # @return [Object] provided record with preloaded associations
77
+ def preload(record, preloads)
78
+ Loader.call([record], preloads)
79
+ record
51
80
  end
52
81
  end
53
-
54
- extend ClassMethods
55
82
  end
56
83
 
84
+ # Preloader adapter for ActiveRecord::Relation
57
85
  class ActiverecordRelation
58
- module ClassMethods
59
- def fit?(objects)
60
- objects.is_a?(ActiveRecord::Relation)
86
+ class << self
87
+ #
88
+ # Checks object is kind of ActiveRecord::Relation
89
+ #
90
+ # @param object [Object] object to check
91
+ #
92
+ # @return [Boolean] whether object is kind of ActiveRecord::Relation
93
+ def fit?(object)
94
+ object.is_a?(ActiveRecord::Relation)
61
95
  end
62
96
 
63
- def preload(objects, preloads)
64
- objects.load
65
- Loader.call(objects.to_a, preloads)
66
- objects
97
+ #
98
+ # Preloads associations to ActiveRecord::Relation
99
+ #
100
+ # @param scope [ActiveRecord::Relation] scope
101
+ #
102
+ # @return [ActiveRecord::Relation] provided scope with preloaded associations
103
+ def preload(scope, preloads)
104
+ scope.load
105
+ Loader.call(scope.to_a, preloads)
106
+ scope
67
107
  end
68
108
  end
69
-
70
- extend ClassMethods
71
109
  end
72
110
 
111
+ # Preloader adapter for Array of ActiveRecord objects
73
112
  class ActiverecordArray
74
- module ClassMethods
75
- def fit?(objects)
76
- objects.is_a?(Array) &&
77
- ActiverecordObject.fit?(objects.first) &&
78
- same_kind?(objects)
113
+ class << self
114
+ #
115
+ # Checks object is an array of ActiveRecord::Base objects
116
+ #
117
+ # @param object [Object] object
118
+ #
119
+ # @return [Boolean] whether object is an array with ActiveRecord objects (and all objects have same class)
120
+ def fit?(object)
121
+ object.is_a?(Array) &&
122
+ ActiverecordObject.fit?(object.first) &&
123
+ same_kind?(object)
79
124
  end
80
125
 
81
- def preload(objects, preloads)
82
- Loader.call(objects, preloads)
83
- objects
126
+ #
127
+ # Preloads associations to array with ActiveRecord::Base objects
128
+ #
129
+ # @param records [Array<ActiveRecord::Base>] ActiveRecord records
130
+ #
131
+ # @return [Array<ActiveRecord::Base>] provided records with preloaded associations
132
+ def preload(records, preloads)
133
+ Loader.call(records, preloads)
134
+ records
84
135
  end
85
136
 
86
137
  private
87
138
 
88
- def same_kind?(objects)
89
- first_object_class = objects.first.class
90
- objects.all? { |object| object.instance_of?(first_object_class) }
139
+ def same_kind?(records)
140
+ first_object_class = records.first.class
141
+ records.all? { |record| record.instance_of?(first_object_class) }
91
142
  end
92
143
  end
93
-
94
- extend ClassMethods
95
144
  end
96
145
 
146
+ # Preloader adapter for Enumerator with ActiveRecord objects
97
147
  class ActiverecordEnumerator
98
- module ClassMethods
99
- def fit?(objects)
100
- objects.is_a?(Enumerator) &&
101
- ActiverecordArray.fit?(objects.to_a)
148
+ class << self
149
+ #
150
+ # Checks object is an Enumerator with each value is a ActiveRecord::Base object
151
+ #
152
+ # @param object [Object] object
153
+ #
154
+ # @return [Boolean] whether object is an Enumerator with each value is a ActiveRecord::Base object
155
+ def fit?(object)
156
+ object.is_a?(Enumerator) &&
157
+ ActiverecordArray.fit?(object.to_a)
102
158
  end
103
159
 
104
- def preload(objects, preloads)
105
- ActiverecordArray.preload(objects.to_a, preloads)
106
- objects
160
+ #
161
+ # Preloads associations to Enumerator with ActiveRecord::Base objects
162
+ #
163
+ # @param enum [Enumerator<ActiveRecord::Base>] enum
164
+ #
165
+ # @return [Enumerator<ActiveRecord::Base>] provided enumerator with preloaded associations
166
+ def preload(enum, preloads)
167
+ ActiverecordArray.preload(enum.to_a, preloads)
168
+ enum
107
169
  end
108
170
  end
109
-
110
- extend ClassMethods
111
171
  end
112
172
  end
113
173
  end
@@ -2,11 +2,52 @@
2
2
 
3
3
  class Serega
4
4
  module SeregaPlugins
5
+ #
6
+ # Plugin that can be used to load attributes values in batches.
7
+ # Each batch loader accepts list of selected keys, context and current attribute point.
8
+ # Each batch loader must return Hash with values grouped by provided keys.
9
+ # There are specific `:default` option that can be used to add default value for missing key.
10
+ #
11
+ # @example
12
+ # class PostSerializer < Serega
13
+ # plugin :batch
14
+ #
15
+ # # Define batch loader via callable class, it must accept three args (keys, context, map_point)
16
+ # attribute :comments_count, batch: { key: :id, loader: PostCommentsCountBatchLoader, default: 0}
17
+ #
18
+ # # Define batch loader via Symbol, later we should define this loader via config.batch_loaders.define(:posts_comments_counter) { ... }
19
+ # attribute :comments_count, batch: { key: :id, loader: :posts_comments_counter, default: 0}
20
+ #
21
+ # # Define batch loader with serializer
22
+ # attribute :comments, serializer: CommentSerializer, batch: { key: :id, loader: :posts_comments, default: []}
23
+ #
24
+ # # Resulted block must return hash like { key => value(s) }
25
+ # config.batch_loaders.define(:posts_comments_counter) do |keys|
26
+ # Comment.group(:post_id).where(post_id: keys).count
27
+ # end
28
+ #
29
+ # # We can return objects that will be automatically serialized if attribute defined with :serializer
30
+ # # Parameter `context` can be used when loading batch
31
+ # # Parameter `map_point` can be used to find nested attributes that will be serialized (`map_point.preloads`)
32
+ # config.batch_loaders.define(:posts_comments) do |keys, context, map_point|
33
+ # Comment.where(post_id: keys).where(is_spam: false).group_by(&:post_id)
34
+ # end
35
+ # end
36
+ #
5
37
  module Batch
38
+ # @return [Symbol] Plugin name
6
39
  def self.plugin_name
7
40
  :batch
8
41
  end
9
42
 
43
+ #
44
+ # Applies plugin code to specific serializer
45
+ #
46
+ # @param serializer_class [Class<Serega>] Current serializer class
47
+ # @param _opts [Hash] Loaded plugins options
48
+ #
49
+ # @return [void]
50
+ #
10
51
  def self.load_plugin(serializer_class, **_opts)
11
52
  require_relative "./lib/loader"
12
53
  require_relative "./lib/loaders"
@@ -15,13 +56,21 @@ class Serega
15
56
  require_relative "./lib/validations/check_opt_batch"
16
57
 
17
58
  serializer_class.extend(ClassMethods)
59
+ serializer_class.include(InstanceMethods)
18
60
  serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
19
61
  serializer_class::SeregaAttribute.include(AttributeInstanceMethods)
20
62
  serializer_class::SeregaMapPoint.include(MapPointInstanceMethods)
21
- serializer_class::SeregaSerializer.include(SeregaSerializerInstanceMethods)
22
63
  serializer_class::SeregaObjectSerializer.include(SeregaObjectSerializerInstanceMethods)
23
64
  end
24
65
 
66
+ #
67
+ # Runs callbacks after plugin was attached
68
+ #
69
+ # @param serializer_class [Class<Serega>] Current serializer class
70
+ # @param opts [Hash] loaded plugins opts
71
+ #
72
+ # @return [void]
73
+ #
25
74
  def self.after_load_plugin(serializer_class, **opts)
26
75
  config = serializer_class.config
27
76
  config.attribute_keys << :batch
@@ -47,6 +96,9 @@ class Serega
47
96
  end
48
97
  end
49
98
 
99
+ #
100
+ # Batch loader config
101
+ #
50
102
  class BatchLoadersConfig
51
103
  attr_reader :opts
52
104
 
@@ -54,6 +106,15 @@ class Serega
54
106
  @opts = opts
55
107
  end
56
108
 
109
+ #
110
+ # Defines batch loader
111
+ #
112
+ # @param loader_name [Symbol] Batch loader name, that is used when defining attribute with batch loader.
113
+ # @param block [Proc] Block that can accept 3 parameters - keys, context, map_point
114
+ # and returns hash where ids are keys and values are batch loaded objects/
115
+ #
116
+ # @return [void]
117
+ #
57
118
  def define(loader_name, &block)
58
119
  unless block
59
120
  raise SeregaError, "Block must be given to batch_loaders.define method"
@@ -67,20 +128,38 @@ class Serega
67
128
  opts[loader_name] = block
68
129
  end
69
130
 
131
+ #
132
+ # Finds previously defined batch loader by name
133
+ #
134
+ # @param loader_name [Symbol]
135
+ #
136
+ # @return [Proc] batch loader block
70
137
  def fetch(loader_name)
71
138
  opts[loader_name] || (raise SeregaError, "Batch loader with name `#{loader_name.inspect}` was not defined. Define example: config.batch_loaders.define(:#{loader_name}) { |keys, ctx, points| ... }")
72
139
  end
73
140
  end
74
141
 
142
+ #
143
+ # Stores batch config for specific attribute
144
+ #
75
145
  class BatchModel
76
146
  attr_reader :opts, :loaders, :many
77
147
 
148
+ #
149
+ # Initializes batch model
150
+ #
151
+ # @param opts [Hash] Attribute :batch option
152
+ # @param loaders [Array] Array of all loaders defined in serialize class
153
+ # @param many [Boolean] Option :many, defined on attribute
154
+ #
155
+ # @return [void]
78
156
  def initialize(opts, loaders, many)
79
157
  @opts = opts
80
158
  @loaders = loaders
81
159
  @many = many
82
160
  end
83
161
 
162
+ # @return [#call] batch loader
84
163
  def loader
85
164
  @batch_loader ||= begin
86
165
  loader = opts[:loader]
@@ -89,6 +168,7 @@ class Serega
89
168
  end
90
169
  end
91
170
 
171
+ # @return [Object] key (uid) of batch loaded object
92
172
  def key
93
173
  @batch_key ||= begin
94
174
  key = opts[:key]
@@ -96,6 +176,7 @@ class Serega
96
176
  end
97
177
  end
98
178
 
179
+ # @return [Object] default value for missing key
99
180
  def default_value
100
181
  if opts.key?(:default)
101
182
  opts[:default]
@@ -105,12 +186,25 @@ class Serega
105
186
  end
106
187
  end
107
188
 
189
+ #
190
+ # Config class additional/patched instance methods
191
+ #
192
+ # @see Serega::SeregaConfig
193
+ #
108
194
  module ConfigInstanceMethods
195
+ #
196
+ # @return [Serega::SeregaPlugins::Batch::BatchLoadersConfig] configuration for batch loaders
197
+ #
109
198
  def batch_loaders
110
199
  @batch_loaders ||= BatchLoadersConfig.new(opts.fetch(:batch).fetch(:loaders))
111
200
  end
112
201
  end
113
202
 
203
+ #
204
+ # Serega class additional/patched class methods
205
+ #
206
+ # @see Serega::SeregaConfig
207
+ #
114
208
  module ClassMethods
115
209
  private
116
210
 
@@ -127,7 +221,14 @@ class Serega
127
221
  end
128
222
  end
129
223
 
224
+ #
225
+ # Serega::SeregaValidations::CheckAttributeParams additional/patched class methods
226
+ #
227
+ # @see Serega::SeregaValidations::CheckAttributeParams
228
+ #
130
229
  module CheckAttributeParamsInstanceMethods
230
+ private
231
+
131
232
  def check_opts
132
233
  super
133
234
 
@@ -135,13 +236,29 @@ class Serega
135
236
  end
136
237
  end
137
238
 
239
+ #
240
+ # Serega::SeregaAttribute additional/patched class methods
241
+ #
242
+ # @see Serega::SeregaAttribute
243
+ #
138
244
  module AttributeInstanceMethods
245
+ #
246
+ # @return [nil, Hash] :batch option
247
+ #
139
248
  def batch
140
249
  opts[:batch]
141
250
  end
142
251
  end
143
252
 
253
+ #
254
+ # Serega::SeregaMapPoint additional/patched class methods
255
+ #
256
+ # @see Serega::SeregaAttribute
257
+ #
144
258
  module MapPointInstanceMethods
259
+ #
260
+ # @return [Serega::Batch::BatchModel] batch model that encapsulates everything needed to load current batch
261
+ #
145
262
  def batch
146
263
  return @batch if instance_variable_defined?(:@batch)
147
264
 
@@ -152,21 +269,30 @@ class Serega
152
269
  end
153
270
  end
154
271
 
155
- module SeregaSerializerInstanceMethods
156
- def initialize(**_args)
157
- super
158
- opts[:batch_loaders] = self.class.serializer_class::SeregaBatchLoaders.new
159
- end
272
+ #
273
+ # Serega additional/patched instance methods
274
+ #
275
+ # @see Serega
276
+ #
277
+ module InstanceMethods
278
+ private
160
279
 
161
- def serialize(*)
280
+ #
281
+ # Loads batch loaded attributes after serialization
282
+ #
283
+ def serialize(object, opts)
284
+ batch_loaders = opts[:batch_loaders] = self.class::SeregaBatchLoaders.new
162
285
  result = super
163
-
164
- opts[:batch_loaders].load_all
165
-
286
+ batch_loaders.load_all
166
287
  result
167
288
  end
168
289
  end
169
290
 
291
+ #
292
+ # SeregaObjectSerializer additional/patched class methods
293
+ #
294
+ # @see Serega::SeregaObjectSerializer
295
+ #
170
296
  module SeregaObjectSerializerInstanceMethods
171
297
  private
172
298
 
@@ -3,19 +3,51 @@
3
3
  class Serega
4
4
  module SeregaPlugins
5
5
  module Batch
6
+ #
7
+ # Encapsulates point and according object_serializer
8
+ # so we can put batch loaded values to this serializer response
9
+ #
6
10
  class SeregaBatchLoader
11
+ #
12
+ # Batch Loader instance methods
13
+ #
7
14
  module InstanceMethods
8
- attr_reader :object_serializer, :point
15
+ # @return [Serega::SeregaMapPoint]
16
+ attr_reader :point
9
17
 
18
+ # @return [Serega::SeregaObjectSerializer]
19
+ attr_reader :object_serializer
20
+
21
+ #
22
+ # Initializes new SeregaBatchLoader
23
+ #
24
+ # @param object_serializer [Serega::SeregaObjectSerializer]
25
+ # @param point [Serega::SeregaMapPoint]
26
+ #
27
+ # @return [Serega::SeregaPlugins::Batch::SeregaBatchLoader]
28
+ #
10
29
  def initialize(object_serializer, point)
11
30
  @object_serializer = object_serializer
12
31
  @point = point
13
32
  end
14
33
 
34
+ #
35
+ # Remembers key and hash container where value for this key must be inserted
36
+ #
37
+ # @param key [Object] key that identifies batch loaded objects
38
+ # @param container [Hash] container where batch loaded objects must be attached
39
+ #
40
+ # @return [void]
41
+ #
15
42
  def remember(key, container)
16
43
  (keys[key] ||= []) << container
17
44
  end
18
45
 
46
+ #
47
+ # Loads this batch and assigns values to remembered containers
48
+ #
49
+ # @return [void]
50
+ #
19
51
  def load
20
52
  keys_values = keys_values()
21
53
 
@@ -3,12 +3,25 @@
3
3
  class Serega
4
4
  module SeregaPlugins
5
5
  module Batch
6
+ # Lists batch loaders registered during serialization
6
7
  class SeregaBatchLoaders
8
+ # BatchLoaders instance methods
7
9
  module InstanceMethods
8
- def get(point, object_serializer)
9
- batch_loaders[point] ||= self.class.serializer_class::SeregaBatchLoader.new(object_serializer, point)
10
+ #
11
+ # Initializes or fetches already initialized batch loader
12
+ #
13
+ # @param map_point [Serega::SeregaMapPoint] current map point
14
+ # @param object_serializer[Serega::SeregaObjectSerializer] current object serializer
15
+ #
16
+ # @return [Serega::SeregaPlugins::Batch::SeregaBatchLoader] Batch Loader
17
+ #
18
+ def get(map_point, object_serializer)
19
+ batch_loaders[map_point] ||= self.class.serializer_class::SeregaBatchLoader.new(object_serializer, map_point)
10
20
  end
11
21
 
22
+ #
23
+ # Loads all registered batches and removes them from registered list
24
+ #
12
25
  def load_all
13
26
  return unless defined?(@batch_loaders)
14
27
 
@@ -3,9 +3,21 @@
3
3
  class Serega
4
4
  module SeregaPlugins
5
5
  module Batch
6
+ # Extensions (mini-plugins) that are enabled when Batch plugin used with other plugins
6
7
  module PluginsExtensions
8
+ #
9
+ # Extension that is used when batch plugin used with :active_record_preloads plugin
10
+ #
7
11
  module ActiveRecordPreloads
12
+ #
13
+ # BatchLoader additional/patched instance methods
14
+ #
15
+ # @see Serega::SeregaPlugins::Batch::SeregaBatchLoader
16
+ #
8
17
  module BatchLoaderInstanceMethods
18
+ private
19
+
20
+ # Preloads required associations to batch-loaded records
9
21
  def keys_values(*)
10
22
  data = super
11
23
 
@@ -21,13 +33,23 @@ class Serega
21
33
  end
22
34
  end
23
35
 
36
+ #
37
+ # Extension that is used when batch plugin used with :formatters plugin
38
+ #
24
39
  module Formatters
40
+ #
41
+ # BatchLoader additional/patched instance methods
42
+ #
43
+ # @see Serega::SeregaPlugins::Batch::SeregaBatchLoader
44
+ #
25
45
  module BatchLoaderInstanceMethods
46
+ private
47
+
26
48
  # Format values after they are prepared
27
49
  def keys_values(*)
28
50
  data = super
29
51
 
30
- formatter = point.attribute.formatter_resolved
52
+ formatter = point.attribute.formatter
31
53
  data.transform_values! { |value| formatter.call(value) } if formatter
32
54
 
33
55
  data
@@ -3,8 +3,20 @@
3
3
  class Serega
4
4
  module SeregaPlugins
5
5
  module Batch
6
+ #
7
+ # Validator for option :key in attribute :batch option
8
+ #
6
9
  class CheckBatchOptKey
7
10
  class << self
11
+ #
12
+ # Checks option :key of attribute :batch option
13
+ #
14
+ # @param key [nil, #call] Attribute :batch option :key
15
+ #
16
+ # @raise [SeregaError] validation error
17
+ #
18
+ # @return [void]
19
+ #
8
20
  def call(key)
9
21
  return if key.is_a?(Symbol)
10
22
 
@@ -3,8 +3,20 @@
3
3
  class Serega
4
4
  module SeregaPlugins
5
5
  module Batch
6
+ #
7
+ # Validator for option :loader in attribute :batch option
8
+ #
6
9
  class CheckBatchOptLoader
7
10
  class << self
11
+ #
12
+ # Checks option :loader of attribute :batch option
13
+ #
14
+ # @param loader [nil, #call] Attribute :batch option :loader
15
+ #
16
+ # @raise [SeregaError] validation error
17
+ #
18
+ # @return [void]
19
+ #
8
20
  def call(loader)
9
21
  return if loader.is_a?(Symbol)
10
22
 
@@ -3,8 +3,20 @@
3
3
  class Serega
4
4
  module SeregaPlugins
5
5
  module Batch
6
+ #
7
+ # Attribute `:batch` option validator
8
+ #
6
9
  class CheckOptBatch
7
10
  class << self
11
+ #
12
+ # Checks attribute :batch option
13
+ #
14
+ # @param opts [Hash] Attribute options
15
+ #
16
+ # @raise [SeregaError] Attribute validation error
17
+ #
18
+ # @return [void]
19
+ #
8
20
  def call(opts, block)
9
21
  return unless opts.key?(:batch)
10
22