serega 0.19.0 → 0.20.1

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: 85e79f7011bb7c55c60c9b39e425faf9137fb4b2f2889332a2e75f1fea1268a7
4
- data.tar.gz: 5358001a693ec3f6c40383cc12c8f44b37764bf5f1b9143bddba338756948e91
3
+ metadata.gz: 11094f59dcd5d1d918604998ac267dbd13297bf0f70a9f3da5fd5ba74eb76b06
4
+ data.tar.gz: 97d1a419769b73937afde735e24210690e2f7702943d60db5be4252301e07255
5
5
  SHA512:
6
- metadata.gz: 66e705d78a97def601c4f3ad79b20a5599cd0b7885b26decea38437428ea18a9ac1d65a55d20042d2c79046343ec36c25ede2795ac1a697dd510976876a91eff
7
- data.tar.gz: 2cb126604c9d0a8eb5679a85daa29bcd830996bca4820d8fadfec5847f78af74602cc1dc2693143cd86fa0160b0f6c61248fcf87a41d1e97ec5e732772962989
6
+ metadata.gz: f9e3bfb207894f09c9c88658bad62e2a28e8b4d44648a74f807d332862b0cd7bdc67870f0d06786de0eb64537fd1a824c5d4f375406b71d18410b63c5a8c5320
7
+ data.tar.gz: 1171f2aabb7ce1c63a9e2f95f5413e9d80a882326ada4fac561b527c8a1adcc263ff19d6224eb070f0ebb333254ff48c9c7f56861ff6418732848cde3ffbc5b5
data/README.md CHANGED
@@ -301,7 +301,7 @@ fields_as_string = 'first_name,enemy'
301
301
  UserSerializer.new(only: fields).to_h(bruce)
302
302
  UserSerializer.to_h(bruce, only: fields)
303
303
  UserSerializer.to_h(bruce, only: fields_as_string)
304
- # => raises Serega::AttributeNotExist, "Attribute 'enemy' not exists"
304
+ # => raises Serega::AttributeNotExist
305
305
 
306
306
  # With no existing attribute and disabled validation
307
307
  fields = %i[first_name enemy]
@@ -1074,7 +1074,10 @@ a single object.
1074
1074
 
1075
1075
  - The `Serega::SeregaError` is a base error raised by this gem.
1076
1076
  - The `Serega::AttributeNotExist` error is raised when validating attributes in
1077
- `:only, :except, :with` modifiers
1077
+ `:only, :except, :with` modifiers. This error contains additional methods:
1078
+
1079
+ - `#serializer` - shows current serializer
1080
+ - `#attributes` - lists not existing attributes
1078
1081
 
1079
1082
  ## Release
1080
1083
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.19.0
1
+ 0.20.1
data/lib/serega/config.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "forwardable"
4
-
5
3
  class Serega
6
4
  #
7
5
  # Stores serialization config
data/lib/serega/errors.rb CHANGED
@@ -11,5 +11,13 @@ class Serega
11
11
  # @example
12
12
  # Serega.new(only: 'FOO')
13
13
  # # => Attribute 'FOO' not exists (Serega::AttributeNotExist)
14
- class AttributeNotExist < SeregaError; end
14
+ class AttributeNotExist < SeregaError
15
+ attr_reader :serializer, :attributes
16
+
17
+ def initialize(message = nil, serializer = nil, attributes = nil)
18
+ super(message)
19
+ @serializer = serializer
20
+ @attributes = attributes
21
+ end
22
+ end
15
23
  end
@@ -38,8 +38,8 @@ class Serega
38
38
 
39
39
  private
40
40
 
41
- def serialize_array(object)
42
- object.map { |obj| serialize_object(obj) }
41
+ def serialize_array(objects)
42
+ objects.map { |object| serialize_object(object) }
43
43
  end
44
44
 
45
45
  # Patched in:
@@ -70,6 +70,7 @@ class Serega
70
70
 
71
71
  # Patched in:
72
72
  # - plugin :if (conditionally skips attaching)
73
+ # - plugin :batch :if extension (removes prepared key)
73
74
  def attach_final_value(final_value, point, container)
74
75
  container[point.name] = final_value
75
76
  end
@@ -79,11 +80,16 @@ class Serega
79
80
  end
80
81
 
81
82
  def relation_value(value, point)
82
- child_plan = point.child_plan
83
- child_serializer = point.child_object_serializer
84
- child_many = point.many
85
- serializer = child_serializer.new(context: context, plan: child_plan, many: child_many, **opts)
86
- serializer.serialize(value)
83
+ child_serializer(point).serialize(value)
84
+ end
85
+
86
+ def child_serializer(point)
87
+ point.child_object_serializer.new(
88
+ context: context,
89
+ plan: point.child_plan,
90
+ many: point.many,
91
+ **opts
92
+ )
87
93
  end
88
94
 
89
95
  def array?(object, many)
@@ -9,8 +9,6 @@ class Serega
9
9
  # SeregaPlanPoint instance methods
10
10
  #
11
11
  module InstanceMethods
12
- extend Forwardable
13
-
14
12
  # Link to current plan this point belongs to
15
13
  # @return [SeregaAttribute] Current plan
16
14
  attr_reader :plan
@@ -27,20 +25,6 @@ class Serega
27
25
  # @return [Hash] Attributes to serialize
28
26
  attr_reader :modifiers
29
27
 
30
- # @!method name
31
- # Attribute `name`
32
- # @see SeregaAttribute::AttributeInstanceMethods#name
33
- # @!method value
34
- # Attribute `value` block
35
- # @see SeregaAttribute::AttributeInstanceMethods#value
36
- # @!method many
37
- # Attribute `many` option
38
- # @see SeregaAttribute::AttributeInstanceMethods#many
39
- # @!method serializer
40
- # Attribute `serializer` option
41
- # @see SeregaAttribute::AttributeInstanceMethods#serializer
42
- def_delegators :@attribute, :name, :value, :many, :serializer
43
-
44
28
  #
45
29
  # Initializes plan point
46
30
  #
@@ -60,6 +44,30 @@ class Serega
60
44
  set_normalized_vars
61
45
  end
62
46
 
47
+ # Attribute `value`
48
+ # @see SeregaAttribute::AttributeInstanceMethods#value
49
+ def value(obj, ctx)
50
+ attribute.value(obj, ctx)
51
+ end
52
+
53
+ # Attribute `name`
54
+ # @see SeregaAttribute::AttributeInstanceMethods#value
55
+ def name
56
+ attribute.name
57
+ end
58
+
59
+ # Attribute `many` option
60
+ # @see SeregaAttribute::AttributeInstanceMethods#many
61
+ def many
62
+ attribute.many
63
+ end
64
+
65
+ # Attribute `serializer` option
66
+ # @see SeregaAttribute::AttributeInstanceMethods#serializer
67
+ def serializer
68
+ attribute.serializer
69
+ end
70
+
63
71
  #
64
72
  # @return [SeregaObjectSerializer] object serializer for child plan
65
73
  #
@@ -54,17 +54,21 @@ class Serega
54
54
  # Checks requirements to load plugin
55
55
  #
56
56
  # @param serializer_class [Class<Serega>] Current serializer class
57
- # @param _opts [Hash] plugins options
57
+ # @param opts [Hash] plugin options
58
58
  #
59
59
  # @return [void]
60
60
  #
61
- def self.before_load_plugin(serializer_class, **_opts)
61
+ def self.before_load_plugin(serializer_class, **opts)
62
+ opts.each_key do |key|
63
+ raise SeregaError, "Plugin #{plugin_name.inspect} does not accept the #{key.inspect} option. No options are allowed"
64
+ end
65
+
62
66
  unless serializer_class.plugin_used?(:preloads)
63
- raise SeregaError, "Please load `plugin :preloads` first"
67
+ raise SeregaError, "Plugin #{plugin_name.inspect} must be loaded after the :preloads plugin. Please load the :preloads plugin first"
64
68
  end
65
69
 
66
70
  if serializer_class.plugin_used?(:batch)
67
- raise SeregaError, "Plugin `activerecord_preloads` must be loaded before `batch`"
71
+ raise SeregaError, "Plugin #{plugin_name.inspect} must be loaded before the :batch plugin"
68
72
  end
69
73
  end
70
74
 
@@ -72,7 +76,7 @@ class Serega
72
76
  # Applies plugin code to specific serializer
73
77
  #
74
78
  # @param serializer_class [Class<Serega>] Current serializer class
75
- # @param _opts [Hash] Loaded plugins options
79
+ # @param _opts [Hash] Plugin options
76
80
  #
77
81
  # @return [void]
78
82
  #
@@ -25,11 +25,30 @@ class Serega
25
25
  :batch
26
26
  end
27
27
 
28
+ # Checks requirements to load plugin
29
+ #
30
+ # @param serializer_class [Class<Serega>] Current serializer class
31
+ # @param opts [Hash] plugin options
32
+ #
33
+ # @return [void]
34
+ #
35
+ def self.before_load_plugin(serializer_class, **opts)
36
+ allowed_keys = %i[auto_hide id_method]
37
+ opts.each_key do |key|
38
+ next if allowed_keys.include?(key)
39
+
40
+ raise SeregaError,
41
+ "Plugin #{plugin_name.inspect} does not accept the #{key.inspect} option. Allowed options:\n" \
42
+ " - :auto_hide [Boolean] - Marks attribute as hidden when it has :batch loader specified\n" \
43
+ " - :id_method [Symbol, #call] - Specified the default method to use to find object identifier"
44
+ end
45
+ end
46
+
28
47
  #
29
48
  # Applies plugin code to specific serializer
30
49
  #
31
50
  # @param serializer_class [Class<Serega>] Current serializer class
32
- # @param _opts [Hash] Loaded plugins options
51
+ # @param _opts [Hash] Plugin options
33
52
  #
34
53
  # @return [void]
35
54
  #
@@ -60,7 +79,7 @@ class Serega
60
79
  # Runs callbacks after plugin was attached
61
80
  #
62
81
  # @param serializer_class [Class<Serega>] Current serializer class
63
- # @param opts [Hash] loaded plugins opts
82
+ # @param opts [Hash] Plugin options
64
83
  #
65
84
  # @return [void]
66
85
  #
@@ -86,6 +105,11 @@ class Serega
86
105
  serializer_class::SeregaAttribute.include(PluginsExtensions::Formatters::SeregaAttributeInstanceMethods)
87
106
  end
88
107
 
108
+ if serializer_class.plugin_used?(:if)
109
+ require_relative "lib/plugins_extensions/if"
110
+ serializer_class::SeregaObjectSerializer.include(PluginsExtensions::If::ObjectSerializerInstanceMethods123)
111
+ end
112
+
89
113
  if serializer_class.plugin_used?(:preloads)
90
114
  require_relative "lib/plugins_extensions/preloads"
91
115
  serializer_class::SeregaAttributeNormalizer.include(PluginsExtensions::Preloads::AttributeNormalizerInstanceMethods)
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module SeregaPlugins
5
+ module Batch
6
+ #
7
+ # Extensions (mini-plugins) that are enabled when :batch plugin used with other plugins
8
+ #
9
+ module PluginsExtensions
10
+ #
11
+ # Extension that is used when :if plugin is loaded
12
+ #
13
+ module If
14
+ #
15
+ # SeregaObjectSerializer additional/patched class methods
16
+ #
17
+ # @see Serega::SeregaObjectSerializer
18
+ #
19
+ module ObjectSerializerInstanceMethods123
20
+ private
21
+
22
+ # Removes key added by `batch` plugin at the start of serialization to preserve attributes ordering
23
+ def attach_final_value(value, point, container)
24
+ container.delete(point.name) if super == SeregaPlugins::If::KEY_SKIPPED
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -48,11 +48,29 @@ class Serega
48
48
  :camel_case
49
49
  end
50
50
 
51
+ # Checks requirements to load plugin
52
+ #
53
+ # @param serializer_class [Class<Serega>] Current serializer class
54
+ # @param opts [Hash] plugin options
55
+ #
56
+ # @return [void]
57
+ #
58
+ def self.before_load_plugin(serializer_class, **opts)
59
+ allowed_keys = %i[transform]
60
+ opts.each_key do |key|
61
+ next if allowed_keys.include?(key)
62
+
63
+ raise SeregaError,
64
+ "Plugin #{plugin_name.inspect} does not accept the #{key.inspect} option. Allowed options:\n" \
65
+ " - :transform [#call] - Custom transformation"
66
+ end
67
+ end
68
+
51
69
  #
52
70
  # Applies plugin code to specific serializer
53
71
  #
54
72
  # @param serializer_class [Class<Serega>] Current serializer class
55
- # @param _opts [Hash] Loaded plugins options
73
+ # @param _opts [Hash] Plugin options
56
74
  #
57
75
  # @return [void]
58
76
  #
@@ -66,7 +84,7 @@ class Serega
66
84
  # Adds config options and runs other callbacks after plugin was loaded
67
85
  #
68
86
  # @param serializer_class [Class<Serega>] Current serializer class
69
- # @param opts [Hash] loaded plugins opts
87
+ # @param opts [Hash] Plugin options
70
88
  #
71
89
  # @return [void]
72
90
  #
@@ -30,13 +30,22 @@ class Serega
30
30
  # Checks requirements and loads additional plugins
31
31
  #
32
32
  # @param serializer_class [Class<Serega>] Current serializer class
33
- # @param opts [Hash] loaded plugins opts
33
+ # @param opts [Hash] Plugin options
34
34
  #
35
35
  # @return [void]
36
36
  #
37
37
  def self.before_load_plugin(serializer_class, **opts)
38
+ allowed_keys = %i[context_metadata_key]
39
+ opts.each_key do |key|
40
+ next if allowed_keys.include?(key)
41
+
42
+ raise SeregaError,
43
+ "Plugin #{plugin_name.inspect} does not accept the #{key.inspect} option. Allowed options:\n" \
44
+ " - :context_metadata_key [Symbol] - The key name that must be used to add metadata. Default is :meta."
45
+ end
46
+
38
47
  unless serializer_class.plugin_used?(:root)
39
- raise SeregaError, "Please load :root plugin first so we can wrap serialization response into top-level hash to add metadata there"
48
+ raise SeregaError, "Plugin #{plugin_name.inspect} must be loaded after the :root plugin. Please load the :root plugin first"
40
49
  end
41
50
  end
42
51
 
@@ -44,7 +53,7 @@ class Serega
44
53
  # Applies plugin code to specific serializer
45
54
  #
46
55
  # @param serializer_class [Class<Serega>] Current serializer class
47
- # @param _opts [Hash] Loaded plugins options
56
+ # @param _opts [Hash] Plugin options
48
57
  #
49
58
  # @return [void]
50
59
  #
@@ -58,7 +67,7 @@ class Serega
58
67
  # Adds config options and runs other callbacks after plugin was loaded
59
68
  #
60
69
  # @param serializer_class [Class<Serega>] Current serializer class
61
- # @param opts [Hash] loaded plugins opts
70
+ # @param opts [Hash] Plugin options
62
71
  #
63
72
  # @return [void]
64
73
  #
@@ -41,11 +41,29 @@ class Serega
41
41
  :depth_limit
42
42
  end
43
43
 
44
+ # Checks requirements
45
+ #
46
+ # @param serializer_class [Class<Serega>] Current serializer class
47
+ # @param opts [Hash] Plugin options
48
+ #
49
+ # @return [void]
50
+ #
51
+ def self.before_load_plugin(serializer_class, **opts)
52
+ allowed_keys = %i[limit]
53
+ opts.each_key do |key|
54
+ next if allowed_keys.include?(key)
55
+
56
+ raise SeregaError,
57
+ "Plugin #{plugin_name.inspect} does not accept the #{key.inspect} option. Allowed options:\n" \
58
+ " - :limit [Integer] - Maximum serialization depth."
59
+ end
60
+ end
61
+
44
62
  #
45
63
  # Applies plugin code to specific serializer
46
64
  #
47
65
  # @param serializer_class [Class<Serega>] Current serializer class
48
- # @param _opts [Hash] Loaded plugins options
66
+ # @param _opts [Hash] Plugin options
49
67
  #
50
68
  # @return [void]
51
69
  #
@@ -58,7 +76,7 @@ class Serega
58
76
  # Adds config options and runs other callbacks after plugin was loaded
59
77
  #
60
78
  # @param serializer_class [Class<Serega>] Current serializer class
61
- # @param opts [Hash] loaded plugins opts
79
+ # @param opts [Hash] Plugin options
62
80
  #
63
81
  # @return [void]
64
82
  #
@@ -35,7 +35,7 @@ class Serega
35
35
  # Applies plugin code to specific serializer
36
36
  #
37
37
  # @param serializer_class [Class<Serega>] Current serializer class
38
- # @param _opts [Hash] Loaded plugins options
38
+ # @param _opts [Hash] Plugin options
39
39
  #
40
40
  # @return [void]
41
41
  #
@@ -51,13 +51,22 @@ class Serega
51
51
  # Checks requirements and loads additional plugins
52
52
  #
53
53
  # @param serializer_class [Class<Serega>] Current serializer class
54
- # @param opts [Hash] loaded plugins opts
54
+ # @param opts [Hash] Plugin options
55
55
  #
56
56
  # @return [void]
57
57
  #
58
58
  def self.before_load_plugin(serializer_class, **opts)
59
+ allowed_keys = %i[formatters]
60
+ opts.each_key do |key|
61
+ next if allowed_keys.include?(key)
62
+
63
+ raise SeregaError,
64
+ "Plugin #{plugin_name.inspect} does not accept the #{key.inspect} option. Allowed options:\n" \
65
+ " - :formatters [Hash<Symbol, #call>] - Formatters (names and according callable values)"
66
+ end
67
+
59
68
  if serializer_class.plugin_used?(:batch)
60
- raise SeregaError, "Plugin `formatters` must be loaded before `batch`"
69
+ raise SeregaError, "Plugin #{plugin_name.inspect} must be loaded before the :batch plugin"
61
70
  end
62
71
  end
63
72
 
@@ -65,7 +74,7 @@ class Serega
65
74
  # Applies plugin code to specific serializer
66
75
  #
67
76
  # @param serializer_class [Class<Serega>] Current serializer class
68
- # @param _opts [Hash] Loaded plugins options
77
+ # @param _opts [Hash] Plugin options
69
78
  #
70
79
  # @return [void]
71
80
  #
@@ -79,7 +88,7 @@ class Serega
79
88
  # Adds config options and runs other callbacks after plugin was loaded
80
89
  #
81
90
  # @param serializer_class [Class<Serega>] Current serializer class
82
- # @param opts [Hash] loaded plugins opts
91
+ # @param opts [Hash] Plugin options
83
92
  #
84
93
  # @return [void]
85
94
  #
@@ -42,16 +42,32 @@ class Serega
42
42
  # end
43
43
  #
44
44
  module If
45
+ # This value must be returned to identify that serialization key was skipped
46
+ KEY_SKIPPED = :_key_skipped_with_serega_if_plugin
47
+
45
48
  # @return [Symbol] Plugin name
46
49
  def self.plugin_name
47
50
  :if
48
51
  end
49
52
 
53
+ # Checks requirements to load plugin
54
+ #
55
+ # @param serializer_class [Class<Serega>] Current serializer class
56
+ # @param opts [Hash] plugin options
57
+ #
58
+ # @return [void]
59
+ #
60
+ def self.before_load_plugin(serializer_class, **opts)
61
+ if serializer_class.plugin_used?(:batch)
62
+ raise SeregaError, "Plugin #{plugin_name.inspect} must be loaded before the :batch plugin"
63
+ end
64
+ end
65
+
50
66
  #
51
67
  # Applies plugin code to specific serializer
52
68
  #
53
69
  # @param serializer_class [Class<Serega>] Current serializer class
54
- # @param _opts [Hash] Loaded plugins options
70
+ # @param _opts [Hash] Plugin options
55
71
  #
56
72
  # @return [void]
57
73
  #
@@ -72,7 +88,7 @@ class Serega
72
88
  # Adds config options and runs other callbacks after plugin was loaded
73
89
  #
74
90
  # @param serializer_class [Class<Serega>] Current serializer class
75
- # @param opts [Hash] loaded plugins opts
91
+ # @param opts [Hash] Plugin options
76
92
  #
77
93
  # @return [void]
78
94
  #
@@ -194,12 +210,13 @@ class Serega
194
210
  private
195
211
 
196
212
  def serialize_point(object, point, _container)
197
- return unless point.satisfy_if_conditions?(object, context)
213
+ return KEY_SKIPPED unless point.satisfy_if_conditions?(object, context)
198
214
  super
199
215
  end
200
216
 
201
217
  def attach_final_value(value, point, _container)
202
- return unless point.satisfy_if_value_conditions?(value, context)
218
+ return KEY_SKIPPED unless point.satisfy_if_value_conditions?(value, context)
219
+
203
220
  super
204
221
  end
205
222
  end
@@ -65,7 +65,7 @@ class Serega
65
65
  def normalize_block(value, const, block)
66
66
  return proc { const } if const
67
67
 
68
- callable = (value || block)
68
+ callable = value || block
69
69
  params_count = SeregaUtils::ParamsCount.call(callable, max_count: 2)
70
70
 
71
71
  case params_count
@@ -46,13 +46,13 @@ class Serega
46
46
  # Checks requirements and loads additional plugins
47
47
  #
48
48
  # @param serializer_class [Class<Serega>] Current serializer class
49
- # @param _opts [Hash] loaded plugins opts
49
+ # @param _opts [Hash] Plugin options
50
50
  #
51
51
  # @return [void]
52
52
  #
53
53
  def self.before_load_plugin(serializer_class, **_opts)
54
54
  unless serializer_class.plugin_used?(:root)
55
- raise SeregaError, "Please load :root plugin first so we can wrap serialization response into top-level hash to add metadata there"
55
+ raise SeregaError, "Plugin #{plugin_name.inspect} must be loaded after the :root plugin. Please load the :root plugin first"
56
56
  end
57
57
  end
58
58
 
@@ -60,7 +60,7 @@ class Serega
60
60
  # Applies plugin code to specific serializer
61
61
  #
62
62
  # @param serializer_class [Class<Serega>] Current serializer class
63
- # @param _opts [Hash] Loaded plugins options
63
+ # @param _opts [Hash] Plugin options
64
64
  #
65
65
  # @return [void]
66
66
  #
@@ -87,7 +87,7 @@ class Serega
87
87
  # Adds config options and runs other callbacks after plugin was loaded
88
88
  #
89
89
  # @param serializer_class [Class<Serega>] Current serializer class
90
- # @param _opts [Hash] loaded plugins opts
90
+ # @param _opts [Hash] Plugin options
91
91
  #
92
92
  # @return [void]
93
93
  #
@@ -51,7 +51,7 @@ class Serega
51
51
  opts.fetch(method_name)
52
52
  end
53
53
 
54
- define_method("#{method_name}=") do |value|
54
+ define_method(:"#{method_name}=") do |value|
55
55
  raise SeregaError, "Must have boolean value, #{value.inspect} provided" if (value != true) && (value != false)
56
56
  opts[method_name] = value
57
57
  end
@@ -70,11 +70,35 @@ class Serega
70
70
  :preloads
71
71
  end
72
72
 
73
+ # Checks requirements to load plugin
74
+ #
75
+ # @param serializer_class [Class<Serega>] Current serializer class
76
+ # @param opts [Hash] plugin options
77
+ #
78
+ # @return [void]
79
+ #
80
+ def self.before_load_plugin(serializer_class, **opts)
81
+ allowed_keys = DEFAULT_CONFIG.keys
82
+ opts.each_key do |key|
83
+ next if allowed_keys.include?(key)
84
+
85
+ raise SeregaError,
86
+ "Plugin #{plugin_name.inspect} does not accept the #{key.inspect} option. Allowed options:\n" \
87
+ " - :auto_preload_attributes_with_delegate [Boolean] - Automatically adds `preload: <delegate_to>` option to attributes with :delegate option specified\n" \
88
+ " - :auto_preload_attributes_with_serializer [Boolean] - Automatically adds `preload: <attribute_name>` option to attributes with :serializer option specified\n" \
89
+ " - :auto_hide_attributes_with_preload [Boolean] - Automatically adds `hide: true` option to attributes with :preload option (specified manually or added automatically)"
90
+ end
91
+
92
+ if serializer_class.plugin_used?(:batch)
93
+ raise SeregaError, "Plugin #{plugin_name.inspect} must be loaded before the :batch plugin"
94
+ end
95
+ end
96
+
73
97
  #
74
98
  # Applies plugin code to specific serializer
75
99
  #
76
100
  # @param serializer_class [Class<Serega>] Current serializer class
77
- # @param _opts [Hash] Loaded plugins options
101
+ # @param _opts [Hash] Plugin options
78
102
  #
79
103
  # @return [void]
80
104
  #
@@ -104,7 +128,7 @@ class Serega
104
128
  # Adds config options and runs other callbacks after plugin was loaded
105
129
  #
106
130
  # @param serializer_class [Class<Serega>] Current serializer class
107
- # @param opts [Hash] loaded plugins opts
131
+ # @param opts [Hash] Plugin options
108
132
  #
109
133
  # @return [void]
110
134
  #
@@ -29,7 +29,7 @@ class Serega
29
29
  # Applies plugin code to specific serializer
30
30
  #
31
31
  # @param serializer_class [Class<Serega>] Current serializer class
32
- # @param _opts [Hash] Loaded plugins options
32
+ # @param _opts [Hash] Plugin options
33
33
  #
34
34
  # @return [void]
35
35
  #
@@ -42,7 +42,7 @@ class Serega
42
42
  # Runs callbacks after plugin was attached
43
43
  #
44
44
  # @param serializer_class [Class<Serega>] Current serializer class
45
- # @param _opts [Hash] loaded plugins opts
45
+ # @param _opts [Hash] Plugin options
46
46
  #
47
47
  # @return [void]
48
48
  #
@@ -60,11 +60,31 @@ class Serega
60
60
  :root
61
61
  end
62
62
 
63
+ # Checks requirements to load plugin
64
+ #
65
+ # @param serializer_class [Class<Serega>] Current serializer class
66
+ # @param opts [Hash] plugin options
67
+ #
68
+ # @return [void]
69
+ #
70
+ def self.before_load_plugin(serializer_class, **opts)
71
+ allowed_keys = %i[root root_one root_many]
72
+ opts.each_key do |key|
73
+ next if allowed_keys.include?(key)
74
+
75
+ raise SeregaError,
76
+ "Plugin #{plugin_name.inspect} does not accept the #{key.inspect} option. Allowed options:\n" \
77
+ " - :root [String, Symbol, nil] Specifies common root keyword used when serializing one or multiple objects\n" \
78
+ " - :root_one [String, Symbol, nil] Specifies root keyword used when serializing one object\n" \
79
+ " - :root_many [String, Symbol, nil] Specifies root keyword used when serializing multiple objects" \
80
+ end
81
+ end
82
+
63
83
  #
64
84
  # Applies plugin code to specific serializer
65
85
  #
66
86
  # @param serializer_class [Class<Serega>] Current serializer class
67
- # @param _opts [Hash] Loaded plugins options
87
+ # @param _opts [Hash] Plugin options
68
88
  #
69
89
  # @return [void]
70
90
  #
@@ -78,7 +98,7 @@ class Serega
78
98
  # Adds config options and runs other callbacks after plugin was loaded
79
99
  #
80
100
  # @param serializer_class [Class<Serega>] Current serializer class
81
- # @param opts [Hash] loaded plugins opts
101
+ # @param opts [Hash] Plugin options
82
102
  #
83
103
  # @return [void]
84
104
  #
@@ -102,9 +122,9 @@ class Serega
102
122
  #
103
123
  # Configures response root key
104
124
  #
105
- # @param root [String, Symbol, nil] Specifies common root when serializing one or multiple objects
106
- # @param one [String, Symbol, nil] Specifies root when serializing one object
107
- # @param many [String, Symbol, nil] Specifies root when serializing multiple objects
125
+ # @param root [String, Symbol, nil] Specifies common root keyword used when serializing one or multiple objects
126
+ # @param one [String, Symbol, nil] Specifies root keyword used when serializing one object
127
+ # @param many [String, Symbol, nil] Specifies root keyword used when serializing multiple objects
108
128
  #
109
129
  # @return [Hash] Configured root names
110
130
  #
@@ -12,7 +12,7 @@ class Serega
12
12
  # Applies plugin code to specific serializer
13
13
  #
14
14
  # @param serializer_class [Class<Serega>] Current serializer class
15
- # @param _opts [Hash] Loaded plugins options
15
+ # @param _opts [Hash] Plugin options
16
16
  #
17
17
  # @return [void]
18
18
  #
@@ -27,7 +27,7 @@ class Serega
27
27
  validate(serializer_class, with) if with
28
28
  validate(serializer_class, except) if except
29
29
 
30
- raise_errors if any_error?
30
+ raise_errors(serializer_class) if any_error?
31
31
  end
32
32
 
33
33
  private
@@ -66,12 +66,19 @@ class Serega
66
66
  end
67
67
 
68
68
  def save_error(name)
69
- full_attribute_name = [*parents_names, name].join(".")
70
- error_attributes << full_attribute_name
69
+ error_attributes << build_full_attribute_name(*parents_names, name)
71
70
  end
72
71
 
73
- def raise_errors
74
- raise Serega::AttributeNotExist, "Not existing attributes: #{error_attributes.join(", ")}"
72
+ def build_full_attribute_name(*names)
73
+ head, *nested = *names
74
+ result = head.to_s # names are symbols, we need not frozen string
75
+ nested.each { |nested_name| result << "(" << nested_name.to_s }
76
+ nested.each { result << ")" }
77
+ result
78
+ end
79
+
80
+ def raise_errors(serializer_class)
81
+ raise Serega::AttributeNotExist.new("Not existing attributes: #{error_attributes.join(", ")}", serializer_class, error_attributes)
75
82
  end
76
83
 
77
84
  def any_error?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serega
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.20.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Glushkov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-17 00:00:00.000000000 Z
11
+ date: 2024-02-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  JSON Serializer
@@ -54,6 +54,7 @@ files:
54
54
  - lib/serega/plugins/batch/lib/modules/plan_point.rb
55
55
  - lib/serega/plugins/batch/lib/plugins_extensions/activerecord_preloads.rb
56
56
  - lib/serega/plugins/batch/lib/plugins_extensions/formatters.rb
57
+ - lib/serega/plugins/batch/lib/plugins_extensions/if.rb
57
58
  - lib/serega/plugins/batch/lib/plugins_extensions/preloads.rb
58
59
  - lib/serega/plugins/batch/lib/validations/check_batch_opt_id_method.rb
59
60
  - lib/serega/plugins/batch/lib/validations/check_batch_opt_loader.rb
@@ -140,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
141
  - !ruby/object:Gem::Version
141
142
  version: '0'
142
143
  requirements: []
143
- rubygems_version: 3.4.22
144
+ rubygems_version: 3.5.6
144
145
  signing_key:
145
146
  specification_version: 4
146
147
  summary: JSON Serializer