serega 0.32.0 → 0.33.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.
- checksums.yaml +4 -4
- data/README.md +20 -21
- data/VERSION +1 -1
- data/lib/serega/batch/auto_resolver_factory.rb +12 -10
- data/lib/serega/config.rb +13 -29
- data/lib/serega.rb +6 -90
- metadata +1 -4
- data/lib/serega/json/adapter.rb +0 -23
- data/lib/serega/json/json.rb +0 -37
- data/lib/serega/json/oj.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5cd7b294e87a2a489db28dc4b77e46a7a359cf667908350a15e74d919a340305
|
4
|
+
data.tar.gz: e273e63a8a9248b44da6fbd4d71be4fc5be3a01308e42fa8222cec76a94a23e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94418c706174af2493fa63da4982a732fdaf5841d1664404f20f142d8e4bf798297375d6dc7d082a470a85eea18defa53975076e7778c468ef5f6faa5c8b8f59
|
7
|
+
data.tar.gz: 7b896b64920aa07a6ba01e4e03967e75cf67a21590978b226e018344e9f116ce0d579289b45eb7a1670989f5fc51591d33546c0f8c9a2dc28ba1fc4ca6120176
|
data/README.md
CHANGED
@@ -143,9 +143,8 @@ end
|
|
143
143
|
|
144
144
|
### Serializing
|
145
145
|
|
146
|
-
We can serialize objects using class
|
147
|
-
same instance methods `#
|
148
|
-
The `to_h` method is also aliased as `call`.
|
146
|
+
We can serialize objects using class method `.call` aliased ad `.to_h` and
|
147
|
+
same instance methods `#call` and its alias `#to_h`.
|
149
148
|
|
150
149
|
```ruby
|
151
150
|
user = OpenStruct.new(username: 'serega')
|
@@ -156,12 +155,6 @@ end
|
|
156
155
|
|
157
156
|
UserSerializer.to_h(user) # => {username: "serega"}
|
158
157
|
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
158
|
```
|
166
159
|
|
167
160
|
If serialized fields are constant, then it's a good idea to initiate the
|
@@ -333,8 +326,8 @@ Named loaders can be defined using the `batch_loader` class method and reused ac
|
|
333
326
|
```ruby
|
334
327
|
class UserSerializer < Serega
|
335
328
|
# Define named loaders
|
336
|
-
|
337
|
-
|
329
|
+
batch :comments_count, ->(users) { Comment.where(user: users).group(:user_id).count }
|
330
|
+
batch :comments_count, CommentsCountLoader # Example with callable class
|
338
331
|
|
339
332
|
# Full attribute example
|
340
333
|
attribute :comments_count, batch: { use: :comments_count },
|
@@ -389,16 +382,22 @@ Here are the default options. Other options can be added with plugins.
|
|
389
382
|
|
390
383
|
```ruby
|
391
384
|
class AppSerializer < Serega
|
392
|
-
#
|
393
|
-
#
|
394
|
-
#
|
395
|
-
config.
|
396
|
-
|
397
|
-
#
|
398
|
-
#
|
399
|
-
#
|
400
|
-
|
401
|
-
|
385
|
+
# With `activerecord_preloads` plugin it automatically adds `preload` option
|
386
|
+
# to attributes with `:delegate` or `:serializer` option.
|
387
|
+
# It helps to preload associations automatically, omitting N+1 requests.
|
388
|
+
config.auto_preload = false
|
389
|
+
|
390
|
+
# Automatically marks as hidden attributes with `:preload` or `:batch` options.
|
391
|
+
# By default is false. Useful option to not make extra DB requests if attribute
|
392
|
+
# was not requested
|
393
|
+
config.auto_hide = false
|
394
|
+
|
395
|
+
# Default method used on serialized object to resolve batch value
|
396
|
+
# For example:
|
397
|
+
# attribute :counter, batch: CounterBatchLoader
|
398
|
+
# # Attribute values will be resolved as:
|
399
|
+
# proc { |object, batches:| batches[:counter][object.id] }
|
400
|
+
config.batch_id_option = :id
|
402
401
|
|
403
402
|
# Disable/enable validation of modifiers (`:with, :except, :only`)
|
404
403
|
# By default, this validation is enabled.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.33.0
|
@@ -22,26 +22,28 @@ class Serega
|
|
22
22
|
# In other cases we should never call tis method here.
|
23
23
|
#
|
24
24
|
def self.get(serializer_class, attribute_name, batch_opt)
|
25
|
+
default_method = serializer_class.config.batch_id_option
|
26
|
+
|
25
27
|
if batch_opt == true # ex: `batch: true`
|
26
|
-
|
27
|
-
|
28
|
+
batch_name = attribute_name
|
29
|
+
batch_id_method = default_method
|
28
30
|
elsif batch_opt.respond_to?(:call) # ex: `batch: FooLoader`
|
29
|
-
serializer_class.
|
30
|
-
|
31
|
-
|
31
|
+
serializer_class.batch(attribute_name, batch_opt)
|
32
|
+
batch_name = attribute_name
|
33
|
+
batch_id_method = default_method
|
32
34
|
else
|
33
35
|
use = batch_opt[:use]
|
34
|
-
|
36
|
+
batch_id_method = batch_opt[:id] || default_method
|
35
37
|
|
36
38
|
if use.respond_to?(:call) # ex: `batch: { use: FooLoader }`
|
37
|
-
|
38
|
-
serializer_class.
|
39
|
+
batch_name = attribute_name
|
40
|
+
serializer_class.batch(batch_name, use)
|
39
41
|
else # ex: `batch: { use: :foo }` || batch: { id: :some_id }
|
40
|
-
|
42
|
+
batch_name = use || attribute_name
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
AutoResolver.new(
|
46
|
+
AutoResolver.new(batch_name, batch_id_method)
|
45
47
|
end
|
46
48
|
end
|
47
49
|
end
|
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
|
-
|
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 `
|
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
|
195
|
-
|
196
|
-
|
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
|
201
|
-
#
|
202
|
-
# @
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
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
|
|
data/lib/serega.rb
CHANGED
@@ -23,8 +23,6 @@ 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
|
-
|
28
26
|
require_relative "serega/attribute"
|
29
27
|
require_relative "serega/attribute_normalizer"
|
30
28
|
require_relative "serega/batch/attribute_loader"
|
@@ -78,7 +76,7 @@ class Serega
|
|
78
76
|
check_serialize_params_class.serializer_class = self
|
79
77
|
const_set(:CheckSerializeParams, check_serialize_params_class)
|
80
78
|
|
81
|
-
# Validates `Serializer.
|
79
|
+
# Validates `Serializer.batch` params
|
82
80
|
check_batch_loader_params_class = Class.new(SeregaValidations::CheckBatchLoaderParams)
|
83
81
|
check_batch_loader_params_class.serializer_class = self
|
84
82
|
const_set(:CheckBatchLoaderParams, check_batch_loader_params_class)
|
@@ -155,7 +153,7 @@ class Serega
|
|
155
153
|
end
|
156
154
|
|
157
155
|
#
|
158
|
-
# Lists batch loaders
|
156
|
+
# Lists defined batch loaders
|
159
157
|
#
|
160
158
|
# @return [Hash] batch loaders list
|
161
159
|
#
|
@@ -184,7 +182,7 @@ class Serega
|
|
184
182
|
# Defines a batch loader
|
185
183
|
#
|
186
184
|
# @example
|
187
|
-
#
|
185
|
+
# batch :tags, PostTagsLoader
|
188
186
|
#
|
189
187
|
# @example with block
|
190
188
|
# batch_loader(:tags) do |posts|
|
@@ -208,7 +206,7 @@ class Serega
|
|
208
206
|
#
|
209
207
|
# @return [#call] Batch loader
|
210
208
|
#
|
211
|
-
def
|
209
|
+
def batch(name, value = nil, &block)
|
212
210
|
raise SeregaError, "Batch loader must be defined with a callable value or block" if (value && block) || (!value && !block)
|
213
211
|
|
214
212
|
batch_loader = self::SeregaBatchLoader.new(name: name, block: value || block)
|
@@ -245,59 +243,7 @@ class Serega
|
|
245
243
|
new(modifiers_opts).to_h(object, serialize_opts)
|
246
244
|
end
|
247
245
|
|
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
|
246
|
+
alias_method :to_h, :call
|
301
247
|
|
302
248
|
private
|
303
249
|
|
@@ -362,7 +308,7 @@ class Serega
|
|
362
308
|
|
363
309
|
# Assign same batch loaders
|
364
310
|
batch_loaders.each_value do |loader|
|
365
|
-
subclass.
|
311
|
+
subclass.batch(loader.name, loader.block)
|
366
312
|
end
|
367
313
|
|
368
314
|
super
|
@@ -431,36 +377,6 @@ class Serega
|
|
431
377
|
@preloads ||= SeregaUtils::PreloadsConstructor.call(plan)
|
432
378
|
end
|
433
379
|
|
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
380
|
private
|
465
381
|
|
466
382
|
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.
|
4
|
+
version: 0.33.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrey Glushkov
|
@@ -37,9 +37,6 @@ files:
|
|
37
37
|
- lib/serega/config.rb
|
38
38
|
- lib/serega/errors.rb
|
39
39
|
- 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
40
|
- lib/serega/object_serializer.rb
|
44
41
|
- lib/serega/plan.rb
|
45
42
|
- lib/serega/plan_point.rb
|
data/lib/serega/json/adapter.rb
DELETED
@@ -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
|
data/lib/serega/json/json.rb
DELETED
@@ -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
|
data/lib/serega/json/oj.rb
DELETED
@@ -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
|