serega 0.19.0 → 0.20.1

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: 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