serega 0.20.1 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +113 -226
  3. data/VERSION +1 -1
  4. data/lib/serega/attribute.rb +31 -3
  5. data/lib/serega/attribute_normalizer.rb +143 -42
  6. data/lib/serega/batch/attribute_loader.rb +70 -0
  7. data/lib/serega/batch/attribute_loaders.rb +59 -0
  8. data/lib/serega/batch/auto_resolver.rb +24 -0
  9. data/lib/serega/batch/auto_resolver_factory.rb +48 -0
  10. data/lib/serega/batch/loader.rb +67 -0
  11. data/lib/serega/config.rb +59 -1
  12. data/lib/serega/object_serializer.rb +11 -9
  13. data/lib/serega/plan.rb +16 -0
  14. data/lib/serega/plan_point.rb +31 -5
  15. data/lib/serega/plugins/activerecord_preloads/activerecord_preloads.rb +42 -23
  16. data/lib/serega/plugins/activerecord_preloads/lib/active_record_objects.rb +31 -0
  17. data/lib/serega/plugins/camel_case/camel_case.rb +1 -1
  18. data/lib/serega/plugins/formatters/formatters.rb +79 -22
  19. data/lib/serega/plugins/if/if.rb +41 -22
  20. data/lib/serega/plugins/if/validations/check_opt_if.rb +27 -6
  21. data/lib/serega/plugins/if/validations/check_opt_if_value.rb +27 -6
  22. data/lib/serega/plugins/if/validations/check_opt_unless.rb +27 -6
  23. data/lib/serega/plugins/if/validations/check_opt_unless_value.rb +27 -6
  24. data/lib/serega/plugins/metadata/meta_attribute.rb +9 -10
  25. data/lib/serega/plugins/metadata/validations/check_block.rb +2 -4
  26. data/lib/serega/plugins/metadata/validations/check_opt_value.rb +2 -3
  27. data/lib/serega/plugins/presenter/presenter.rb +1 -1
  28. data/lib/serega/plugins/string_modifiers/parse_string_modifiers.rb +43 -30
  29. data/lib/serega/utils/format_user_preloads.rb +58 -0
  30. data/lib/serega/utils/method_signature.rb +89 -0
  31. data/lib/serega/utils/preload_paths.rb +53 -0
  32. data/lib/serega/utils/preloads_constructor.rb +77 -0
  33. data/lib/serega/validations/attribute/check_block.rb +38 -6
  34. data/lib/serega/validations/attribute/check_opt_batch.rb +101 -0
  35. data/lib/serega/validations/attribute/check_opt_const.rb +1 -0
  36. data/lib/serega/validations/attribute/check_opt_delegate.rb +1 -0
  37. data/lib/serega/validations/attribute/check_opt_method.rb +1 -0
  38. data/lib/serega/{plugins/preloads/validations → validations/attribute}/check_opt_preload.rb +2 -2
  39. data/lib/serega/{plugins/preloads/validations → validations/attribute}/check_opt_preload_path.rb +3 -3
  40. data/lib/serega/validations/attribute/check_opt_value.rb +35 -9
  41. data/lib/serega/validations/check_attribute_params.rb +3 -2
  42. data/lib/serega/validations/check_batch_loader_params.rb +80 -0
  43. data/lib/serega/validations/initiate/check_modifiers.rb +1 -1
  44. data/lib/serega.rb +110 -11
  45. metadata +17 -37
  46. data/lib/serega/plugins/batch/batch.rb +0 -168
  47. data/lib/serega/plugins/batch/lib/batch_config.rb +0 -77
  48. data/lib/serega/plugins/batch/lib/loader.rb +0 -113
  49. data/lib/serega/plugins/batch/lib/loaders.rb +0 -45
  50. data/lib/serega/plugins/batch/lib/modules/attribute.rb +0 -26
  51. data/lib/serega/plugins/batch/lib/modules/attribute_normalizer.rb +0 -78
  52. data/lib/serega/plugins/batch/lib/modules/check_attribute_params.rb +0 -22
  53. data/lib/serega/plugins/batch/lib/modules/config.rb +0 -23
  54. data/lib/serega/plugins/batch/lib/modules/object_serializer.rb +0 -46
  55. data/lib/serega/plugins/batch/lib/modules/plan_point.rb +0 -22
  56. data/lib/serega/plugins/batch/lib/plugins_extensions/activerecord_preloads.rb +0 -43
  57. data/lib/serega/plugins/batch/lib/plugins_extensions/formatters.rb +0 -54
  58. data/lib/serega/plugins/batch/lib/plugins_extensions/if.rb +0 -31
  59. data/lib/serega/plugins/batch/lib/plugins_extensions/preloads.rb +0 -34
  60. data/lib/serega/plugins/batch/lib/validations/check_batch_opt_id_method.rb +0 -43
  61. data/lib/serega/plugins/batch/lib/validations/check_batch_opt_loader.rb +0 -59
  62. data/lib/serega/plugins/batch/lib/validations/check_opt_batch.rb +0 -62
  63. data/lib/serega/plugins/preloads/lib/format_user_preloads.rb +0 -60
  64. data/lib/serega/plugins/preloads/lib/modules/attribute.rb +0 -28
  65. data/lib/serega/plugins/preloads/lib/modules/attribute_normalizer.rb +0 -99
  66. data/lib/serega/plugins/preloads/lib/modules/check_attribute_params.rb +0 -22
  67. data/lib/serega/plugins/preloads/lib/modules/config.rb +0 -19
  68. data/lib/serega/plugins/preloads/lib/modules/plan_point.rb +0 -41
  69. data/lib/serega/plugins/preloads/lib/preload_paths.rb +0 -53
  70. data/lib/serega/plugins/preloads/lib/preloads_config.rb +0 -62
  71. data/lib/serega/plugins/preloads/lib/preloads_constructor.rb +0 -79
  72. data/lib/serega/plugins/preloads/preloads.rb +0 -162
  73. data/lib/serega/utils/params_count.rb +0 -50
  74. data/lib/serega/validations/utils/check_extra_keyword_arg.rb +0 -33
@@ -1,168 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaPlugins
5
- #
6
- # Plugin `:batch`
7
- #
8
- # Must be used to omit N+1 when loading attributes values.
9
- #
10
- # @example Quick example
11
- #
12
- # class AppSerializer
13
- # plugin :batch, id_method: :id
14
- # end
15
- #
16
- # class UserSerializer < AppSerializer
17
- # attribute :comments_count, batch: { loader: CommentsCountBatchLoader }, default: 0
18
- # attribute :company, serializer: CompanySerializer, batch: { loader: UserCompanyBatchLoader }
19
- # end
20
- #
21
- module Batch
22
- # Returns plugin name
23
- # @return [Symbol] Plugin name
24
- def self.plugin_name
25
- :batch
26
- end
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
-
47
- #
48
- # Applies plugin code to specific serializer
49
- #
50
- # @param serializer_class [Class<Serega>] Current serializer class
51
- # @param _opts [Hash] Plugin options
52
- #
53
- # @return [void]
54
- #
55
- def self.load_plugin(serializer_class, **_opts)
56
- require_relative "lib/batch_config"
57
- require_relative "lib/loader"
58
- require_relative "lib/loaders"
59
- require_relative "lib/modules/attribute"
60
- require_relative "lib/modules/attribute_normalizer"
61
- require_relative "lib/modules/check_attribute_params"
62
- require_relative "lib/modules/config"
63
- require_relative "lib/modules/object_serializer"
64
- require_relative "lib/modules/plan_point"
65
- require_relative "lib/validations/check_batch_opt_id_method"
66
- require_relative "lib/validations/check_batch_opt_loader"
67
- require_relative "lib/validations/check_opt_batch"
68
-
69
- serializer_class.extend(ClassMethods)
70
- serializer_class.include(InstanceMethods)
71
- serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
72
- serializer_class::SeregaAttribute.include(AttributeInstanceMethods)
73
- serializer_class::SeregaAttributeNormalizer.include(AttributeNormalizerInstanceMethods)
74
- serializer_class::SeregaPlanPoint.include(PlanPointInstanceMethods)
75
- serializer_class::SeregaObjectSerializer.include(SeregaObjectSerializerInstanceMethods)
76
- end
77
-
78
- #
79
- # Runs callbacks after plugin was attached
80
- #
81
- # @param serializer_class [Class<Serega>] Current serializer class
82
- # @param opts [Hash] Plugin options
83
- #
84
- # @return [void]
85
- #
86
- def self.after_load_plugin(serializer_class, **opts)
87
- serializer_class::SeregaConfig.include(ConfigInstanceMethods)
88
-
89
- batch_loaders_class = Class.new(SeregaBatchLoaders)
90
- batch_loaders_class.serializer_class = serializer_class
91
- serializer_class.const_set(:SeregaBatchLoaders, batch_loaders_class)
92
-
93
- batch_loader_class = Class.new(SeregaBatchLoader)
94
- batch_loader_class.serializer_class = serializer_class
95
- serializer_class.const_set(:SeregaBatchLoader, batch_loader_class)
96
-
97
- if serializer_class.plugin_used?(:activerecord_preloads)
98
- require_relative "lib/plugins_extensions/activerecord_preloads"
99
- serializer_class::SeregaBatchLoader.include(PluginsExtensions::ActiveRecordPreloads::BatchLoaderInstanceMethods)
100
- end
101
-
102
- if serializer_class.plugin_used?(:formatters)
103
- require_relative "lib/plugins_extensions/formatters"
104
- serializer_class::SeregaBatchLoader.include(PluginsExtensions::Formatters::BatchLoaderInstanceMethods)
105
- serializer_class::SeregaAttribute.include(PluginsExtensions::Formatters::SeregaAttributeInstanceMethods)
106
- end
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
-
113
- if serializer_class.plugin_used?(:preloads)
114
- require_relative "lib/plugins_extensions/preloads"
115
- serializer_class::SeregaAttributeNormalizer.include(PluginsExtensions::Preloads::AttributeNormalizerInstanceMethods)
116
- end
117
-
118
- config = serializer_class.config
119
- config.attribute_keys << :batch
120
- config.opts[:batch] = {loaders: {}, id_method: nil, auto_hide: false}
121
- config.batch.auto_hide = opts[:auto_hide] if opts.key?(:auto_hide)
122
- config.batch.id_method = opts[:id_method] if opts.key?(:id_method)
123
- end
124
-
125
- #
126
- # Serega class additional/patched class methods
127
- #
128
- # @see Serega::SeregaConfig
129
- #
130
- module ClassMethods
131
- private
132
-
133
- def inherited(subclass)
134
- super
135
-
136
- batch_loaders_class = Class.new(self::SeregaBatchLoaders)
137
- batch_loaders_class.serializer_class = subclass
138
- subclass.const_set(:SeregaBatchLoaders, batch_loaders_class)
139
-
140
- batch_loader_class = Class.new(self::SeregaBatchLoader)
141
- batch_loader_class.serializer_class = subclass
142
- subclass.const_set(:SeregaBatchLoader, batch_loader_class)
143
- end
144
- end
145
-
146
- #
147
- # Serega additional/patched instance methods
148
- #
149
- # @see Serega::InstanceMethods
150
- #
151
- module InstanceMethods
152
- private
153
-
154
- #
155
- # Loads batch loaded attributes after serialization
156
- #
157
- def serialize(object, opts)
158
- batch_loaders = opts[:batch_loaders] = self.class::SeregaBatchLoaders.new
159
- result = super
160
- batch_loaders.load_all
161
- result
162
- end
163
- end
164
- end
165
-
166
- register_plugin(Batch.plugin_name, Batch)
167
- end
168
- end
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaPlugins
5
- module Batch
6
- #
7
- # Batch plugin config
8
- #
9
- class BatchConfig
10
- attr_reader :opts
11
-
12
- def initialize(opts)
13
- @opts = opts
14
- end
15
-
16
- #
17
- # Defines batch loader
18
- #
19
- # @param loader_name [Symbol] Batch loader name, that is used when defining attribute with batch loader.
20
- # @param block [Proc] Block that can accept 3 parameters - ids, context, plan_point
21
- # and returns hash with ids as keys and values are batch loaded objects
22
- #
23
- # @return [void]
24
- #
25
- def define(loader_name, callable = nil, &block)
26
- if (!callable && !block) || (callable && block)
27
- raise SeregaError, "Batch loader can be specified with one of arguments - callable value or &block"
28
- end
29
-
30
- callable ||= block
31
- SeregaValidations::Utils::CheckExtraKeywordArg.call(callable, "batch loader `#{loader_name}`")
32
- params_count = SeregaUtils::ParamsCount.call(callable, max_count: 3)
33
-
34
- if params_count > 3
35
- raise SeregaError, "Batch loader can have maximum 3 parameters (ids, context, plan)"
36
- end
37
-
38
- loaders[loader_name] = callable
39
- end
40
-
41
- # Shows defined loaders
42
- # @return [Hash] defined loaders
43
- def loaders
44
- opts[:loaders]
45
- end
46
-
47
- # Shows option to auto hide attributes with :batch specified
48
- # @return [Boolean, nil] option value
49
- def auto_hide
50
- opts[:auto_hide]
51
- end
52
-
53
- # @param value [Boolean] New :auto_hide option value
54
- # @return [Boolean] New option value
55
- def auto_hide=(value)
56
- raise SeregaError, "Must have boolean value, #{value.inspect} provided" if (value != true) && (value != false)
57
- opts[:auto_hide] = value
58
- end
59
-
60
- # Shows method name or callable object needed to get object identifier for batch load
61
- # @return [Symbol, #call, nil] Default method name or callable object to get identifier
62
- def id_method
63
- opts[:id_method]
64
- end
65
-
66
- # Sets new identifier method name or callable value needed for batch loading
67
- #
68
- # @param value [Symbol, #call] New :id_method value
69
- # @return [Boolean] New option value
70
- def id_method=(value)
71
- CheckBatchOptIdMethod.call(value)
72
- opts[:id_method] = value
73
- end
74
- end
75
- end
76
- end
77
- end
@@ -1,113 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaPlugins
5
- module Batch
6
- #
7
- # Encapsulates point and according object_serializer
8
- # so we can put batch loaded values to this serializer response
9
- #
10
- class SeregaBatchLoader
11
- #
12
- # Batch Loader instance methods
13
- #
14
- module InstanceMethods
15
- # @return [Serega::SeregaPlanPoint]
16
- attr_reader :point
17
-
18
- # @return [Serega::SeregaObjectSerializer]
19
- attr_reader :object_serializer
20
-
21
- #
22
- # Initializes new SeregaBatchLoader
23
- #
24
- # @param object_serializer [Serega::SeregaObjectSerializer]
25
- # @param point [Serega::SeregaPlanPoint]
26
- #
27
- # @return [Serega::SeregaPlugins::Batch::SeregaBatchLoader]
28
- #
29
- def initialize(object_serializer, point)
30
- @object_serializer = object_serializer
31
- @point = point
32
- end
33
-
34
- #
35
- # Remembers key and hash container where value for this key must be inserted
36
- #
37
- # @param key [Object] key that identifies batch loaded objects
38
- # @param container [Hash] container where batch loaded objects must be attached
39
- #
40
- # @return [void]
41
- #
42
- def remember(key, container)
43
- (keys[key] ||= []) << container
44
- end
45
-
46
- #
47
- # Loads this batch and assigns values to remembered containers
48
- #
49
- # @return [void]
50
- #
51
- def load
52
- keys_values = keys_values()
53
-
54
- each_key do |key, container|
55
- value = keys_values.fetch(key) { point.batch[:default] }
56
- final_value = object_serializer.__send__(:final_value, value, point)
57
- object_serializer.__send__(:attach_final_value, final_value, point, container)
58
- end
59
- end
60
-
61
- private
62
-
63
- def keys
64
- @keys ||= {}
65
- end
66
-
67
- def each_key
68
- keys.each do |key, containers|
69
- containers.each do |container|
70
- yield(key, container)
71
- end
72
- end
73
- end
74
-
75
- # Patched in:
76
- # - plugin batch (extension :activerecord_preloads - preloads data to found values)
77
- # - plugin batch (extension :formatters - formats values)
78
- def keys_values
79
- ids = keys.keys
80
-
81
- keys_values = load_keys_values(ids)
82
- validate(keys_values)
83
-
84
- keys_values
85
- end
86
-
87
- def load_keys_values(ids)
88
- point.batch[:loader].call(ids, object_serializer.context, point)
89
- rescue => error
90
- raise reraise_with_serialized_attribute_details(error, point)
91
- end
92
-
93
- def validate(keys_values)
94
- return if keys_values.is_a?(Hash)
95
-
96
- attribute_name = "#{point.class.serializer_class}.#{point.name}"
97
- raise SeregaError, "Batch loader for `#{attribute_name}` must return Hash, but #{keys_values.inspect} was returned"
98
- end
99
-
100
- def reraise_with_serialized_attribute_details(error, point)
101
- raise error.exception(<<~MESSAGE.strip)
102
- #{error.message}
103
- (when serializing '#{point.name}' attribute in #{self.class.serializer_class})
104
- MESSAGE
105
- end
106
- end
107
-
108
- include InstanceMethods
109
- extend Serega::SeregaHelpers::SerializerClassHelper
110
- end
111
- end
112
- end
113
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaPlugins
5
- module Batch
6
- # Lists batch loaders registered during serialization
7
- class SeregaBatchLoaders
8
- # BatchLoaders instance methods
9
- module InstanceMethods
10
- #
11
- # Initializes or fetches already initialized batch loader
12
- #
13
- # @param plan_point [Serega::SeregaPlanPoint] current plan point
14
- # @param object_serializer[Serega::SeregaObjectSerializer] current object serializer
15
- #
16
- # @return [Serega::SeregaPlugins::Batch::SeregaBatchLoader] Batch Loader
17
- #
18
- def get(plan_point, object_serializer)
19
- batch_loaders[plan_point] ||= self.class.serializer_class::SeregaBatchLoader.new(object_serializer, plan_point)
20
- end
21
-
22
- #
23
- # Loads all registered batches and removes them from registered list
24
- #
25
- def load_all
26
- return unless defined?(@batch_loaders)
27
-
28
- while (_point, batch_loader = batch_loaders.shift)
29
- batch_loader.load
30
- end
31
- end
32
-
33
- private
34
-
35
- def batch_loaders
36
- @batch_loaders ||= {}.compare_by_identity
37
- end
38
- end
39
-
40
- include InstanceMethods
41
- extend Serega::SeregaHelpers::SerializerClassHelper
42
- end
43
- end
44
- end
45
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaPlugins
5
- module Batch
6
- #
7
- # Serega::SeregaAttribute additional/patched class methods
8
- #
9
- # @see Serega::SeregaAttribute
10
- #
11
- module AttributeInstanceMethods
12
- #
13
- # @return [nil, Hash] :batch option
14
- #
15
- attr_reader :batch
16
-
17
- private
18
-
19
- def set_normalized_vars(normalizer)
20
- super
21
- @batch = normalizer.batch
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,78 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaPlugins
5
- module Batch
6
- #
7
- # SeregaAttributeNormalizer additional/patched instance methods
8
- #
9
- # @see SeregaAttributeNormalizer::AttributeInstanceMethods
10
- #
11
- module AttributeNormalizerInstanceMethods
12
- #
13
- # Returns normalized attribute :batch option with prepared :key and
14
- # :default options. Option :loader will be prepared at serialization
15
- # time as loaders are usually defined after attributes.
16
- #
17
- # @return [Hash] attribute :batch normalized options
18
- #
19
- def batch
20
- return @batch if instance_variable_defined?(:@batch)
21
-
22
- @batch = prepare_batch
23
- end
24
-
25
- private
26
-
27
- #
28
- # Patch for original `prepare_hide` method
29
- #
30
- # Marks attribute hidden if auto_hide option was set and attribute has batch loader
31
- #
32
- def prepare_hide
33
- res = super
34
- return res unless res.nil?
35
-
36
- if batch
37
- self.class.serializer_class.config.batch.auto_hide || nil
38
- end
39
- end
40
-
41
- def prepare_batch
42
- batch = init_opts[:batch]
43
- return unless batch
44
-
45
- loader = prepare_batch_loader(batch[:loader])
46
-
47
- id_method = batch[:id_method] || self.class.serializer_class.config.batch.id_method
48
- id_method = prepare_batch_id_method(id_method)
49
-
50
- {loader: loader, id_method: id_method, default: default}
51
- end
52
-
53
- def prepare_batch_id_method(id_method)
54
- return proc { |object| object.public_send(id_method) } if id_method.is_a?(Symbol)
55
-
56
- params_count = SeregaUtils::ParamsCount.call(id_method, max_count: 2)
57
- case params_count
58
- when 0 then proc { id_method.call }
59
- when 1 then proc { |object| id_method.call(object) }
60
- else id_method
61
- end
62
- end
63
-
64
- def prepare_batch_loader(loader)
65
- loader = self.class.serializer_class.config.batch.loaders.fetch(loader) if loader.is_a?(Symbol)
66
-
67
- params_count = SeregaUtils::ParamsCount.call(loader, max_count: 3)
68
- case params_count
69
- when 0 then proc { loader.call }
70
- when 1 then proc { |object| loader.call(object) }
71
- when 2 then proc { |object, context| loader.call(object, context) }
72
- else loader
73
- end
74
- end
75
- end
76
- end
77
- end
78
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaPlugins
5
- module Batch
6
- #
7
- # Serega::SeregaValidations::CheckAttributeParams additional/patched class methods
8
- #
9
- # @see Serega::SeregaValidations::CheckAttributeParams
10
- #
11
- module CheckAttributeParamsInstanceMethods
12
- private
13
-
14
- def check_opts
15
- super
16
-
17
- CheckOptBatch.call(opts, block, self.class.serializer_class)
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaPlugins
5
- module Batch
6
- #
7
- # Config class additional/patched instance methods
8
- #
9
- # @see Serega::SeregaConfig
10
- #
11
- module ConfigInstanceMethods
12
- #
13
- # Returns all batch loaders registered for current serializer
14
- #
15
- # @return [Serega::SeregaPlugins::Batch::BatchConfig] configuration for batch loaded attributes
16
- #
17
- def batch
18
- @batch ||= BatchConfig.new(opts.fetch(:batch))
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaPlugins
5
- module Batch
6
- #
7
- # SeregaObjectSerializer additional/patched class methods
8
- #
9
- # @see Serega::SeregaObjectSerializer
10
- #
11
- module SeregaObjectSerializerInstanceMethods
12
- private
13
-
14
- def attach_value(object, point, container)
15
- batch = point.batch
16
- return super unless batch
17
-
18
- remember_key_for_batch_loading(batch, object, point, container)
19
- end
20
-
21
- def remember_key_for_batch_loading(batch, object, point, container)
22
- id = batch[:id_method].call(object, context)
23
- batch_loader(point).remember(id, container)
24
- container[point.name] = nil # Reserve attribute place in resulted hash. We will set correct value later
25
- end
26
-
27
- def batch_loader(point)
28
- batch_loaders = opts[:batch_loaders]
29
- raise_batch_plugin_for_serializer_not_defined(point) unless batch_loaders
30
- batch_loaders.get(point, self)
31
- end
32
-
33
- def raise_batch_plugin_for_serializer_not_defined(point)
34
- root_plan = point.plan
35
- root_plan = plan.parent_plan_point.plan while root_plan.parent_plan_point
36
- current_serializer = root_plan.serializer_class
37
- nested_serializer = self.class.serializer_class
38
-
39
- raise SeregaError,
40
- "Plugin :batch must be added to current serializer (#{current_serializer})" \
41
- " to load attributes with :batch option in nested serializer (#{nested_serializer})"
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaPlugins
5
- module Batch
6
- #
7
- # Serega::SeregaPlanPoint additional/patched class methods
8
- #
9
- # @see SeregaAttribute
10
- #
11
- module PlanPointInstanceMethods
12
- #
13
- # Returns attribute :batch option with prepared loader
14
- # @return [Hash] attribute :batch option
15
- #
16
- def batch
17
- attribute.batch
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,43 +0,0 @@
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 :batch plugin used with :active_record_preloads plugin
12
- #
13
- module ActiveRecordPreloads
14
- #
15
- # BatchLoader additional/patched instance methods
16
- #
17
- # @see Serega::SeregaPlugins::Batch::SeregaBatchLoader
18
- #
19
- module BatchLoaderInstanceMethods
20
- private
21
-
22
- # Preloads required associations to batch-loaded records
23
- def keys_values
24
- data = super
25
-
26
- if point.child_plan
27
- associations = point.preloads
28
- return data if associations.empty?
29
-
30
- records = data.values
31
- records.flatten!(1)
32
-
33
- ActiverecordPreloads::Preloader.preload(records, associations)
34
- end
35
-
36
- data
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
43
- end