serega 0.32.0 → 0.33.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: 06b324510e423bf61c19d440e522246d6d2223a5228a415a1fd5fcdbd87fd147
4
- data.tar.gz: 5a31066675d38ad2c10032a6d9d7fdd9921db001a11e7b3916887a5215d1ab51
3
+ metadata.gz: 94fe2e370dea04c0bedcb7bed7f7f3b6f9ad9ff49a4c39367429929b5bc68e7e
4
+ data.tar.gz: 65cbab835785d14d8c17aba1ba6eff21b8abb9689eba2e4f15e28d68ee60cea9
5
5
  SHA512:
6
- metadata.gz: 2da3083d578120365246d6b912777dc3d0c36a0dac1a09d4a0af0c5eeea6b398510b5f9dd5f7ca016c3d8d196c58f6990c39cee627646601d44682585b23e7de
7
- data.tar.gz: e0389486ffdbf381d2db837bc7157a87224374abe8402f2b6d5bcd32e75a6cca72111bb38cb9b0955323af9774395a117d2e660725cbb1017e5a496390d7a923
6
+ metadata.gz: 9600ce857e2f2fd0836da34cec422eda2472e945a9c3fd94d4e4c9de7fb95e3ddb147b5ac59dc3c575695787fcb9634b9c1fc7cc512590b2da17e6ec492e9271
7
+ data.tar.gz: 7fa17d2686eb63a64b38cd7fea6a006de17497425a77f17a8619d112de8ca7b361549bcc5c0b03fd06c2bf842aec04f366d3aa5c63ae3b40b5e794b666a3a327
data/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/serega.svg)](https://badge.fury.io/rb/serega)
4
4
  [![GitHub Actions](https://github.com/aglushkov/serega/actions/workflows/main.yml/badge.svg?event=push)](https://github.com/aglushkov/serega/actions/workflows/main.yml)
5
- [![Test Coverage](https://api.codeclimate.com/v1/badges/f10c0659e16e25e49faa/test_coverage)](https://codeclimate.com/github/aglushkov/serega/test_coverage)
6
- [![Maintainability](https://api.codeclimate.com/v1/badges/f10c0659e16e25e49faa/maintainability)](https://codeclimate.com/github/aglushkov/serega/maintainability)
7
5
 
8
6
  The Serega Ruby Serializer provides easy and powerful DSL to describe your
9
7
  objects and serialize them to Hash or JSON.
@@ -143,9 +141,8 @@ end
143
141
 
144
142
  ### Serializing
145
143
 
146
- We can serialize objects using class methods `.to_h`, `.to_json`, `.as_json` and
147
- same instance methods `#to_h`, `#to_json`, `#as_json`.
148
- The `to_h` method is also aliased as `call`.
144
+ We can serialize objects using class method `.call` aliased ad `.to_h` and
145
+ same instance methods `#call` and its alias `#to_h`.
149
146
 
150
147
  ```ruby
151
148
  user = OpenStruct.new(username: 'serega')
@@ -156,12 +153,6 @@ end
156
153
 
157
154
  UserSerializer.to_h(user) # => {username: "serega"}
158
155
  UserSerializer.to_h([user]) # => [{username: "serega"}]
159
-
160
- UserSerializer.to_json(user) # => '{"username":"serega"}'
161
- UserSerializer.to_json([user]) # => '[{"username":"serega"}]'
162
-
163
- UserSerializer.as_json(user) # => {"username":"serega"}
164
- UserSerializer.as_json([user]) # => [{"username":"serega"}]
165
156
  ```
166
157
 
167
158
  If serialized fields are constant, then it's a good idea to initiate the
@@ -333,8 +324,8 @@ Named loaders can be defined using the `batch_loader` class method and reused ac
333
324
  ```ruby
334
325
  class UserSerializer < Serega
335
326
  # Define named loaders
336
- batch_loader :comments_count, ->(users) { Comment.where(user: users).group(:user_id).count }
337
- batch_loader :comments_count, CommentsCountLoader # Example with callable class
327
+ batch :comments_count, ->(users) { Comment.where(user: users).group(:user_id).count }
328
+ batch :comments_count, CommentsCountLoader # Example with callable class
338
329
 
339
330
  # Full attribute example
340
331
  attribute :comments_count, batch: { use: :comments_count },
@@ -373,8 +364,8 @@ Custom loaders can be provided directly using the `:use` option with any callabl
373
364
  ```ruby
374
365
  class UserSerializer < Serega
375
366
  # Define named loaders
376
- batch_loader :facebook_likes, FacebookLikesLoader
377
- batch_loader :twitter_likes, TwitterLikesLoader
367
+ batch :facebook_likes, FacebookLikesLoader
368
+ batch :twitter_likes, TwitterLikesLoader
378
369
 
379
370
  # Summarize likes
380
371
  attribute :likes_count,
@@ -389,16 +380,22 @@ Here are the default options. Other options can be added with plugins.
389
380
 
390
381
  ```ruby
391
382
  class AppSerializer < Serega
392
- # Configure adapter to serialize to JSON.
393
- # It is `JSON.dump` by default. But if the Oj gem is loaded, then the default
394
- # is changed to `Oj.dump(data, mode: :compat)`
395
- config.to_json = ->(data) { Oj.dump(data, mode: :compat) }
396
-
397
- # Configure adapter to de-serialize JSON.
398
- # De-serialization is used only for the `#as_json` method.
399
- # It is `JSON.parse` by default.
400
- # When the Oj gem is loaded, then the default is `Oj.load(data)`
401
- config.from_json = ->(data) { Oj.load(data) }
383
+ # With `activerecord_preloads` plugin it automatically adds `preload` option
384
+ # to attributes with `:delegate` or `:serializer` option.
385
+ # It helps to preload associations automatically, omitting N+1 requests.
386
+ config.auto_preload = false
387
+
388
+ # Automatically marks as hidden attributes with `:preload` or `:batch` options.
389
+ # By default is false. Useful option to not make extra DB requests if attribute
390
+ # was not requested
391
+ config.auto_hide = false
392
+
393
+ # Default method used on serialized object to resolve batch value
394
+ # For example:
395
+ # attribute :counter, batch: CounterBatchLoader
396
+ # # Attribute values will be resolved as:
397
+ # proc { |object, batches:| batches[:counter][object.id] }
398
+ config.batch_id_option = :id
402
399
 
403
400
  # Disable/enable validation of modifiers (`:with, :except, :only`)
404
401
  # By default, this validation is enabled.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.32.0
1
+ 0.33.1
@@ -191,22 +191,18 @@ class Serega
191
191
  def prepare_const_block
192
192
  return unless init_opts.key?(:const)
193
193
 
194
- const = init_opts[:const]
195
- proc { const }
194
+ AttributeValueResolvers::ConstResolver.get(init_opts[:const])
196
195
  end
197
196
 
198
197
  def prepare_keyword_block
199
- key_method_name = method_name
200
- proc do |object|
201
- object.public_send(key_method_name)
202
- end
198
+ AttributeValueResolvers::KeywordResolver.get(method_name)
203
199
  end
204
200
 
205
201
  def prepare_batch_loader_block
206
202
  batch_opt = init_opts[:batch]
207
203
  return unless batch_opt
208
204
 
209
- SeregaBatch::AutoResolverFactory.get(self.class.serializer_class, name, batch_opt)
205
+ AttributeValueResolvers::BatchResolver.get(self.class.serializer_class, name, batch_opt)
210
206
  end
211
207
 
212
208
  def prepare_batch_loaders
@@ -238,16 +234,7 @@ class Serega
238
234
  delegate_to = delegate[:to]
239
235
 
240
236
  allow_nil = delegate.fetch(:allow_nil) { config.delegate_default_allow_nil }
241
-
242
- if allow_nil
243
- proc do |object|
244
- object.public_send(delegate_to)&.public_send(key_method_name)
245
- end
246
- else
247
- proc do |object|
248
- object.public_send(delegate_to).public_send(key_method_name)
249
- end
250
- end
237
+ AttributeValueResolvers::DelegateResolver.get(delegate_to, key_method_name, allow_nil)
251
238
  end
252
239
 
253
240
  # Prepares preloads
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ #
5
+ # Attribute value resolvers
6
+ #
7
+ module AttributeValueResolvers
8
+ #
9
+ # Builds value resolver class for attributes with :batch option
10
+ #
11
+ class BatchResolver
12
+ #
13
+ # Generates callable block to find attribute value when attribute with :batch
14
+ # option has no block or manual :value option.
15
+ #
16
+ # In other cases we should never get here as attribute value/block option must be manually defined.
17
+ #
18
+ # It handles this cases:
19
+ # - `attribute :foo, batch: true`
20
+ # - `attribute :foo, batch: FooLoader`
21
+ # - `attribute :foo, batch: { id: :foo_id }`
22
+ # - `attribute :foo, batch: { use: FooLoader, id: foo_id }`
23
+ # - `attribute :foo, batch: { use: :foo_loader, id: foo_id }`
24
+ #
25
+ def self.get(serializer_class, attribute_name, batch_opt)
26
+ default_method = serializer_class.config.batch_id_option
27
+
28
+ if batch_opt == true # ex: `batch: true`
29
+ batch_name = attribute_name
30
+ batch_id_method = default_method
31
+ elsif batch_opt.respond_to?(:call) # ex: `batch: FooLoader`
32
+ serializer_class.batch(attribute_name, batch_opt)
33
+ batch_name = attribute_name
34
+ batch_id_method = default_method
35
+ else
36
+ use = batch_opt[:use]
37
+ batch_id_method = batch_opt[:id] || default_method
38
+
39
+ if use.respond_to?(:call) # ex: `batch: { use: FooLoader }`
40
+ batch_name = attribute_name
41
+ serializer_class.batch(batch_name, use)
42
+ else # ex: `batch: { use: :foo }` || batch: { id: :some_id }
43
+ batch_name = use || attribute_name
44
+ end
45
+ end
46
+
47
+ Batch.new(batch_name, batch_id_method)
48
+ end
49
+ end
50
+
51
+ #
52
+ # Builds value resolver class for attributes with :batch option
53
+ #
54
+ class Batch
55
+ def initialize(loader_name, id_method)
56
+ @loader_name = loader_name
57
+ @id_method = id_method
58
+ end
59
+
60
+ # Finds object attribute value from hash of batch_loaded values
61
+ def call(obj, batches:)
62
+ batches.fetch(@loader_name)[obj.public_send(@id_method)]
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ #
5
+ # Attribute value resolvers
6
+ #
7
+ module AttributeValueResolvers
8
+ #
9
+ # Builds value resolver class for attributes with :const option
10
+ #
11
+ class ConstResolver
12
+ #
13
+ # Creates resolver that returns constant value
14
+ #
15
+ # @param const_value [Object] constant value to return
16
+ # @return [Const] resolver instance
17
+ #
18
+ def self.get(const_value)
19
+ Const.new(const_value)
20
+ end
21
+ end
22
+
23
+ #
24
+ # Value resolver class for attributes with :const option
25
+ #
26
+ class Const
27
+ def initialize(const_value)
28
+ @const_value = const_value
29
+ end
30
+
31
+ #
32
+ # Returns the constant value
33
+ #
34
+ # @return [Object] the constant value
35
+ #
36
+ def call
37
+ @const_value
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ #
5
+ # Attribute value resolvers
6
+ #
7
+ module AttributeValueResolvers
8
+ #
9
+ # Builds value resolver class for attributes with :delegate option
10
+ #
11
+ class DelegateResolver
12
+ #
13
+ # Creates resolver that delegates method call to another object
14
+ #
15
+ # @param delegate_to [Symbol] method to call on object to get delegated object
16
+ # @param method_name [Symbol] method to call on delegated object
17
+ # @param allow_nil [Boolean] whether to use safe navigation when delegated object is nil
18
+ # @return [Delegate, DelegateAllowNil] resolver instance
19
+ #
20
+ def self.get(delegate_to, method_name, allow_nil)
21
+ allow_nil ? DelegateAllowNil.new(delegate_to, method_name) : Delegate.new(delegate_to, method_name)
22
+ end
23
+ end
24
+
25
+ #
26
+ # Value resolver class for attributes with :delegate (with :allow_nil) option
27
+ #
28
+ class DelegateAllowNil
29
+ def initialize(delegate_to, method_name)
30
+ @delegate_to = delegate_to
31
+ @method_name = method_name
32
+ end
33
+
34
+ #
35
+ # Delegates method call to another object with safe navigation
36
+ #
37
+ # @param object [Object] the object to delegate from
38
+ # @return [Object, nil] result of delegated method call or nil if delegated object is nil
39
+ #
40
+ def call(object)
41
+ object.public_send(delegate_to)&.public_send(method_name)
42
+ end
43
+
44
+ private
45
+
46
+ attr_reader :delegate_to, :method_name
47
+ end
48
+
49
+ #
50
+ # Value resolver class for attributes with :delegate (without :allow_nil) option
51
+ #
52
+ class Delegate
53
+ def initialize(delegate_to, method_name)
54
+ @delegate_to = delegate_to
55
+ @method_name = method_name
56
+ end
57
+
58
+ #
59
+ # Delegates method call to another object
60
+ #
61
+ # @param object [Object] the object to delegate from
62
+ # @return [Object] result of delegated method call
63
+ #
64
+ def call(object)
65
+ object.public_send(@delegate_to).public_send(@method_name)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ #
5
+ # Attribute value resolvers
6
+ #
7
+ module AttributeValueResolvers
8
+ #
9
+ # Builds value resolver class for attributes with :keyword option
10
+ #
11
+ class KeywordResolver
12
+ #
13
+ # Creates resolver that calls method on object
14
+ #
15
+ # @param keyword [Symbol] method name to call on object
16
+ # @return [Keyword] resolver instance
17
+ #
18
+ def self.get(keyword)
19
+ Keyword.new(keyword)
20
+ end
21
+ end
22
+
23
+ #
24
+ # Value resolver class for attributes with :keyword option
25
+ #
26
+ class Keyword
27
+ def initialize(keyword)
28
+ @keyword = keyword
29
+ end
30
+
31
+ #
32
+ # Calls the keyword method on the object
33
+ #
34
+ # @param object [Object] the object to call method on
35
+ # @return [Object] result of method call
36
+ #
37
+ def call(object)
38
+ object.public_send(@keyword)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -13,7 +13,7 @@ class Serega
13
13
  def initialize(point)
14
14
  @point = point
15
15
  @objects = []
16
- @serialized_object_attachers = {}
16
+ @serialized_object_attachers = []
17
17
  end
18
18
 
19
19
  # Stores object with attacher to find and attach attribute values in batch later.
@@ -22,7 +22,7 @@ class Serega
22
22
  # @return [void]
23
23
  def store(object, attacher)
24
24
  objects << object
25
- serialized_object_attachers[object] = attacher
25
+ serialized_object_attachers << [object, attacher]
26
26
  end
27
27
 
28
28
  # Loads serialized values for all stored objects for current attribute
data/lib/serega/config.rb CHANGED
@@ -33,12 +33,7 @@ class Serega
33
33
  max_cached_plans_per_serializer_count: 0,
34
34
  auto_preload: {has_delegate_option: false, has_serializer_option: false},
35
35
  auto_hide: {has_preload_option: false, has_batch_option: false},
36
- # auto_preload_attributes_with_delegate: false,
37
- # auto_preload_attributes_with_serializer: false,
38
- # auto_hide_attributes_with_preload: false,
39
- # hide_batch_attributes: false,
40
- to_json: (SeregaJSON.adapter == :oj) ? SeregaJSON::OjDump : SeregaJSON::JSONDump,
41
- from_json: (SeregaJSON.adapter == :oj) ? SeregaJSON::OjLoad : SeregaJSON::JSONLoad
36
+ batch_id_option: :id
42
37
  }.freeze
43
38
  # :nocov:
44
39
 
@@ -82,7 +77,7 @@ class Serega
82
77
  opts.fetch(:attribute_keys)
83
78
  end
84
79
 
85
- # Returns options names allowed in `to_h, to_json, as_json` methods
80
+ # Returns options names allowed in `call, to_h` methods
86
81
  # @return [Array<Symbol>] Allowed options keys for serialization
87
82
  def serialize_keys
88
83
  opts.fetch(:serialize_keys)
@@ -191,30 +186,19 @@ class Serega
191
186
  opts[:check_attribute_name] = value
192
187
  end
193
188
 
194
- # Returns current `to_json` adapter
195
- # @return [#call] Callable that used to construct JSON
196
- def to_json
197
- opts.fetch(:to_json)
189
+ # Returns current batch_id_option
190
+ def batch_id_option
191
+ opts.fetch(:batch_id_option)
198
192
  end
199
193
 
200
- # Sets current `to_json` adapter
201
- # @param value [#call] Callable that used to construct JSON
202
- # @return [#call] Provided callable object
203
- def to_json=(value)
204
- opts[:to_json] = value
205
- end
206
-
207
- # Returns current `from_json` adapter
208
- # @return [#call] Callable that used to parse JSON
209
- def from_json
210
- opts.fetch(:from_json)
211
- end
212
-
213
- # Sets current `from_json` adapter
214
- # @param value [#call] Callable that used to parse JSON
215
- # @return [#call] Provided callable object
216
- def from_json=(value)
217
- opts[:from_json] = value
194
+ # Sets :batch_id_option config option
195
+ #
196
+ # @param value [Symbol] Set :batch_id_option config option
197
+ #
198
+ # @return [Symbol] New :check_attribute_name config option
199
+ def batch_id_option=(value)
200
+ raise SeregaError, "Must have Symbol value, #{value.inspect} provided" unless value.is_a?(Symbol)
201
+ opts[:batch_id_option] = value
218
202
  end
219
203
  end
220
204
 
@@ -128,12 +128,31 @@ class Serega
128
128
 
129
129
  def prepare_if_option(if_option)
130
130
  return unless if_option
131
- return proc { |val| val.public_send(if_option) } if if_option.is_a?(Symbol)
131
+ return KeywordConditionResolver.new(if_option) if if_option.is_a?(Symbol)
132
132
 
133
133
  if_option
134
134
  end
135
135
  end
136
136
 
137
+ #
138
+ # Resolves keyword-based conditions for if/unless options
139
+ #
140
+ class KeywordConditionResolver
141
+ def initialize(keyword)
142
+ @keyword = keyword
143
+ end
144
+
145
+ #
146
+ # Calls the keyword method on the object
147
+ #
148
+ # @param object [Object] the object to call method on
149
+ # @return [Object] result of method call
150
+ #
151
+ def call(object)
152
+ object.public_send(@keyword)
153
+ end
154
+ end
155
+
137
156
  #
138
157
  # SeregaAttribute additional/patched instance methods
139
158
  #
data/lib/serega.rb CHANGED
@@ -23,14 +23,14 @@ require_relative "serega/utils/preload_paths"
23
23
  require_relative "serega/utils/preloads_constructor"
24
24
  require_relative "serega/utils/symbol_name"
25
25
  require_relative "serega/utils/to_hash"
26
- require_relative "serega/json/adapter"
27
-
26
+ require_relative "serega/attribute_value_resolvers/batch"
27
+ require_relative "serega/attribute_value_resolvers/const"
28
+ require_relative "serega/attribute_value_resolvers/delegate"
29
+ require_relative "serega/attribute_value_resolvers/keyword"
28
30
  require_relative "serega/attribute"
29
31
  require_relative "serega/attribute_normalizer"
30
32
  require_relative "serega/batch/attribute_loader"
31
33
  require_relative "serega/batch/attribute_loaders"
32
- require_relative "serega/batch/auto_resolver"
33
- require_relative "serega/batch/auto_resolver_factory"
34
34
  require_relative "serega/batch/loader"
35
35
  require_relative "serega/validations/utils/check_allowed_keys"
36
36
  require_relative "serega/validations/utils/check_opt_is_bool"
@@ -78,7 +78,7 @@ class Serega
78
78
  check_serialize_params_class.serializer_class = self
79
79
  const_set(:CheckSerializeParams, check_serialize_params_class)
80
80
 
81
- # Validates `Serializer.batch_loader` params
81
+ # Validates `Serializer.batch` params
82
82
  check_batch_loader_params_class = Class.new(SeregaValidations::CheckBatchLoaderParams)
83
83
  check_batch_loader_params_class.serializer_class = self
84
84
  const_set(:CheckBatchLoaderParams, check_batch_loader_params_class)
@@ -155,7 +155,7 @@ class Serega
155
155
  end
156
156
 
157
157
  #
158
- # Lists batch loaders
158
+ # Lists defined batch loaders
159
159
  #
160
160
  # @return [Hash] batch loaders list
161
161
  #
@@ -184,7 +184,7 @@ class Serega
184
184
  # Defines a batch loader
185
185
  #
186
186
  # @example
187
- # batch_loader :tags, PostTagsLoader
187
+ # batch :tags, PostTagsLoader
188
188
  #
189
189
  # @example with block
190
190
  # batch_loader(:tags) do |posts|
@@ -208,7 +208,7 @@ class Serega
208
208
  #
209
209
  # @return [#call] Batch loader
210
210
  #
211
- def batch_loader(name, value = nil, &block)
211
+ def batch(name, value = nil, &block)
212
212
  raise SeregaError, "Batch loader must be defined with a callable value or block" if (value && block) || (!value && !block)
213
213
 
214
214
  batch_loader = self::SeregaBatchLoader.new(name: name, block: value || block)
@@ -245,59 +245,7 @@ class Serega
245
245
  new(modifiers_opts).to_h(object, serialize_opts)
246
246
  end
247
247
 
248
- #
249
- # Serializes provided object to Hash
250
- #
251
- # @param object [Object] Serialized object
252
- # @param opts [Hash, nil] Serializer modifiers and other instantiating options
253
- # @option opts [Array, Hash, String, Symbol] :only The only attributes to serialize
254
- # @option opts [Array, Hash, String, Symbol] :except Attributes to hide
255
- # @option opts [Array, Hash, String, Symbol] :with Attributes (usually hidden) to serialize additionally
256
- # @option opts [Boolean] :validate Validates provided modifiers (Default is true)
257
- # @option opts [Hash] :context Serialization context
258
- # @option opts [Boolean] :many Set true if provided multiple objects (Default `object.is_a?(Enumerable)`)
259
- #
260
- # @return [Hash] Serialization result
261
- #
262
- def to_h(object, opts = nil)
263
- call(object, opts)
264
- end
265
-
266
- #
267
- # Serializes provided object to JSON string
268
- #
269
- # @param object [Object] Serialized object
270
- # @param opts [Hash, nil] Serializer modifiers and other instantiating options
271
- # @option opts [Array, Hash, String, Symbol] :only The only attributes to serialize
272
- # @option opts [Array, Hash, String, Symbol] :except Attributes to hide
273
- # @option opts [Array, Hash, String, Symbol] :with Attributes (usually hidden) to serialize additionally
274
- # @option opts [Boolean] :validate Validates provided modifiers (Default is true)
275
- # @option opts [Hash] :context Serialization context
276
- # @option opts [Boolean] :many Set true if provided multiple objects (Default `object.is_a?(Enumerable)`)
277
- #
278
- # @return [String] Serialization result
279
- #
280
- def to_json(object, opts = nil)
281
- config.to_json.call(to_h(object, opts))
282
- end
283
-
284
- #
285
- # Serializes provided object as JSON
286
- #
287
- # @param object [Object] Serialized object
288
- # @param opts [Hash, nil] Serializer modifiers and other instantiating options
289
- # @option opts [Array, Hash, String, Symbol] :only The only attributes to serialize
290
- # @option opts [Array, Hash, String, Symbol] :except Attributes to hide
291
- # @option opts [Array, Hash, String, Symbol] :with Attributes (usually hidden) to serialize additionally
292
- # @option opts [Boolean] :validate Validates provided modifiers (Default is true)
293
- # @option opts [Hash] :context Serialization context
294
- # @option opts [Boolean] :many Set true if provided multiple objects (Default `object.is_a?(Enumerable)`)
295
- #
296
- # @return [Hash] Serialization result
297
- #
298
- def as_json(object, opts = nil)
299
- config.from_json.call(to_json(object, opts))
300
- end
248
+ alias_method :to_h, :call
301
249
 
302
250
  private
303
251
 
@@ -362,7 +310,7 @@ class Serega
362
310
 
363
311
  # Assign same batch loaders
364
312
  batch_loaders.each_value do |loader|
365
- subclass.batch_loader(loader.name, loader.block)
313
+ subclass.batch(loader.name, loader.block)
366
314
  end
367
315
 
368
316
  super
@@ -431,36 +379,6 @@ class Serega
431
379
  @preloads ||= SeregaUtils::PreloadsConstructor.call(plan)
432
380
  end
433
381
 
434
- #
435
- # Serializes provided object to JSON string
436
- #
437
- # @param object [Object] Serialized object
438
- # @param opts [Hash, nil] Serializer modifiers and other instantiating options
439
- # @option opts [Hash] :context Serialization context
440
- # @option opts [Boolean] :many Set true if provided multiple objects (Default `object.is_a?(Enumerable)`)
441
- #
442
- # @return [Hash] Serialization result
443
- #
444
- def to_json(object, opts = nil)
445
- hash = to_h(object, opts)
446
- config.to_json.call(hash)
447
- end
448
-
449
- #
450
- # Serializes provided object as JSON
451
- #
452
- # @param object [Object] Serialized object
453
- # @param opts [Hash, nil] Serializer modifiers and other instantiating options
454
- # @option opts [Hash] :context Serialization context
455
- # @option opts [Boolean] :many Set true if provided multiple objects (Default `object.is_a?(Enumerable)`)
456
- #
457
- # @return [Hash] Serialization result
458
- #
459
- def as_json(object, opts = nil)
460
- json = to_json(object, opts)
461
- config.from_json.call(json)
462
- end
463
-
464
382
  private
465
383
 
466
384
  attr_reader :opts
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.32.0
4
+ version: 0.33.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Glushkov
@@ -29,17 +29,16 @@ files:
29
29
  - lib/serega.rb
30
30
  - lib/serega/attribute.rb
31
31
  - lib/serega/attribute_normalizer.rb
32
+ - lib/serega/attribute_value_resolvers/batch.rb
33
+ - lib/serega/attribute_value_resolvers/const.rb
34
+ - lib/serega/attribute_value_resolvers/delegate.rb
35
+ - lib/serega/attribute_value_resolvers/keyword.rb
32
36
  - lib/serega/batch/attribute_loader.rb
33
37
  - lib/serega/batch/attribute_loaders.rb
34
- - lib/serega/batch/auto_resolver.rb
35
- - lib/serega/batch/auto_resolver_factory.rb
36
38
  - lib/serega/batch/loader.rb
37
39
  - lib/serega/config.rb
38
40
  - lib/serega/errors.rb
39
41
  - lib/serega/helpers/serializer_class_helper.rb
40
- - lib/serega/json/adapter.rb
41
- - lib/serega/json/json.rb
42
- - lib/serega/json/oj.rb
43
42
  - lib/serega/object_serializer.rb
44
43
  - lib/serega/plan.rb
45
44
  - lib/serega/plan_point.rb
@@ -122,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
121
  - !ruby/object:Gem::Version
123
122
  version: '0'
124
123
  requirements: []
125
- rubygems_version: 3.7.1
124
+ rubygems_version: 3.7.2
126
125
  specification_version: 4
127
126
  summary: JSON Serializer
128
127
  test_files: []
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaBatch
5
- #
6
- # Automatically generated resolver for batch_loader
7
- #
8
- class AutoResolver
9
- attr_reader :loader_name
10
- attr_reader :id_method
11
-
12
- def initialize(loader_name, id_method)
13
- @loader_name = loader_name
14
- @id_method = id_method
15
- end
16
-
17
- # Finds object attribute value from hash of batch_loaded values for all
18
- # serialized objects
19
- def call(obj, batches:)
20
- batches.fetch(loader_name)[obj.public_send(id_method)]
21
- end
22
- end
23
- end
24
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaBatch
5
- #
6
- # Factory generates callable object that should be able to take
7
- # batch loaded results, current object, and find attribute value for this
8
- # object
9
- #
10
- class AutoResolverFactory
11
- #
12
- # Generates callable block to find attribute value when attribute with :batch
13
- # option has no block or manual :value option.
14
- #
15
- # It handles this cases:
16
- # - `attribute :foo, batch: true`
17
- # - `attribute :foo, batch: FooLoader`
18
- # - `attribute :foo, batch: { id: :foo_id }`
19
- # - `attribute :foo, batch: { use: FooLoader, id: foo_id }`
20
- # - `attribute :foo, batch: { use: :foo_loader, id: foo_id }`
21
- #
22
- # In other cases we should never call tis method here.
23
- #
24
- def self.get(serializer_class, attribute_name, batch_opt)
25
- if batch_opt == true # ex: `batch: true`
26
- loader_name = attribute_name
27
- loader_id_method = :id
28
- elsif batch_opt.respond_to?(:call) # ex: `batch: FooLoader`
29
- serializer_class.batch_loader(attribute_name, batch_opt)
30
- loader_name = attribute_name
31
- loader_id_method = :id
32
- else
33
- use = batch_opt[:use]
34
- loader_id_method = batch_opt[:id] || :id
35
-
36
- if use.respond_to?(:call) # ex: `batch: { use: FooLoader }`
37
- loader_name = attribute_name
38
- serializer_class.batch_loader(loader_name, use)
39
- else # ex: `batch: { use: :foo }` || batch: { id: :some_id }
40
- loader_name = use || attribute_name
41
- end
42
- end
43
-
44
- AutoResolver.new(loader_name, loader_id_method)
45
- end
46
- end
47
- end
48
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- #
5
- # JSON adapters
6
- #
7
- module SeregaJSON
8
- # Current JSON adapter
9
- #
10
- # @return [Symbol] Current JSON adapter name - :oj or :json
11
- def self.adapter
12
- @adapter ||=
13
- if defined?(::Oj)
14
- require_relative "oj"
15
- :oj
16
- else
17
- require "json"
18
- require_relative "json"
19
- :json
20
- end
21
- end
22
- end
23
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaJSON
5
- #
6
- # JSON dump adapter for ::JSON
7
- #
8
- class JSONDump
9
- #
10
- # Dumps data to JSON string
11
- #
12
- # @param data [Object] Anything
13
- #
14
- # @return [String] Data serialized to JSON
15
- #
16
- def self.call(data)
17
- ::JSON.dump(data)
18
- end
19
- end
20
-
21
- #
22
- # JSON parse adapter for ::JSON
23
- #
24
- class JSONLoad
25
- #
26
- # Loads object from JSON string
27
- #
28
- # @param json_string [String] JSON String
29
- #
30
- # @return [Object] Deserialized data
31
- #
32
- def self.call(json_string)
33
- ::JSON.parse(json_string)
34
- end
35
- end
36
- end
37
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaJSON
5
- #
6
- # JSON dump adapter for ::Oj
7
- #
8
- class OjDump
9
- # Default Oj serialization options
10
- OPTS = {mode: :compat}.freeze
11
-
12
- #
13
- # Dumps data to JSON string
14
- #
15
- # @param data [Object] Anything
16
- #
17
- # @return [String] Data serialized to JSON
18
- #
19
- def self.call(data)
20
- ::Oj.dump(data, OPTS)
21
- end
22
- end
23
-
24
- #
25
- # JSON parse adapter for ::Oj
26
- #
27
- class OjLoad
28
- #
29
- # Loads object from JSON string
30
- #
31
- # @param json_string [String] JSON String
32
- #
33
- # @return [Object] Deserialized data
34
- #
35
- def self.call(json_string)
36
- ::Oj.load(json_string)
37
- end
38
- end
39
- end
40
- end