alba 1.6.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/alba/resource.rb CHANGED
@@ -1,13 +1,17 @@
1
1
  require_relative 'association'
2
+ require_relative 'conditional_attribute'
3
+ require_relative 'constants'
2
4
  require_relative 'typed_attribute'
5
+ require_relative 'nested_attribute'
3
6
  require_relative 'deprecation'
7
+ require_relative 'layout'
4
8
 
5
9
  module Alba
6
10
  # This module represents what should be serialized
7
11
  module Resource
8
12
  # @!parse include InstanceMethods
9
13
  # @!parse extend ClassMethods
10
- DSLS = {_attributes: {}, _key: nil, _key_for_collection: nil, _meta: nil, _transform_type: :none, _transforming_root_key: false, _on_error: nil, _on_nil: nil, _layout: nil}.freeze # rubocop:disable Layout/LineLength
14
+ DSLS = {_attributes: {}, _key: nil, _key_for_collection: nil, _meta: nil, _transform_type: :none, _transforming_root_key: false, _on_error: nil, _on_nil: nil, _layout: nil, _collection_key: nil}.freeze # rubocop:disable Layout/LineLength
11
15
  private_constant :DSLS
12
16
 
13
17
  WITHIN_DEFAULT = Object.new.freeze
@@ -35,74 +39,91 @@ module Alba
35
39
  # @param within [Object, nil, false, true] determines what associations to be serialized. If not set, it serializes all associations.
36
40
  def initialize(object, params: {}, within: WITHIN_DEFAULT)
37
41
  @object = object
38
- @params = params.freeze
42
+ @params = params
39
43
  @within = within
40
44
  @method_existence = {} # Cache for `respond_to?` result
41
- DSLS.each_key { |name| instance_variable_set("@#{name}", self.class.public_send(name)) }
45
+ DSLS.each_key { |name| instance_variable_set("@#{name}", self.class.__send__(name)) }
42
46
  end
43
47
 
44
48
  # Serialize object into JSON string
45
49
  #
46
- # @param key [Symbol, nil, true] DEPRECATED, use root_key instead
47
50
  # @param root_key [Symbol, nil, true]
48
51
  # @param meta [Hash] metadata for this seialization
49
52
  # @return [String] serialized JSON string
50
- def serialize(key: nil, root_key: nil, meta: {})
51
- Alba::Deprecation.warn '`key` option to `serialize` method is deprecated, use `root_key` instead.' if key
52
- key = key.nil? && root_key.nil? ? fetch_key : root_key || key
53
- hash = if key && key != ''
54
- h = {key.to_s => serializable_hash}
55
- hash_with_metadata(h, meta)
56
- else
57
- serializable_hash
58
- end
59
- serialize_with(hash)
60
- end
61
- alias to_json serialize
53
+ def serialize(root_key: nil, meta: {})
54
+ serialize_with(as_json(root_key: root_key, meta: meta))
55
+ end
56
+
57
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.0')
58
+ # For Rails compatibility
59
+ # The first options is a dummy parameter but required
60
+ # You can pass empty Hash if you don't want to pass any arguments
61
+ #
62
+ # @see #serialize
63
+ # @see https://github.com/rails/rails/blob/7-0-stable/actionpack/lib/action_controller/metal/renderers.rb#L156
64
+ def to_json(options, root_key: nil, meta: {})
65
+ _to_json(root_key, meta, options)
66
+ end
67
+ else
68
+ # For Rails compatibility
69
+ # The first options is a dummy parameter
70
+ #
71
+ # @see #serialize
72
+ # @see https://github.com/rails/rails/blob/7-0-stable/actionpack/lib/action_controller/metal/renderers.rb#L156
73
+ def to_json(options = {}, root_key: nil, meta: {})
74
+ _to_json(root_key, meta, options)
75
+ end
76
+ end
77
+
78
+ # Returns a Hash correspondng {Resource#serialize}
79
+ #
80
+ # @param root_key [Symbol, nil, true]
81
+ # @param meta [Hash] metadata for this seialization
82
+ # @param symbolize_root_key [Boolean] determines if root key should be symbolized
83
+ # @return [Hash]
84
+ def as_json(root_key: nil, meta: {})
85
+ key = root_key.nil? ? fetch_key : root_key.to_s
86
+ if key && !key.empty?
87
+ h = {key => serializable_hash}
88
+ hash_with_metadata(h, meta)
89
+ else
90
+ serializable_hash
91
+ end
92
+ end
62
93
 
63
94
  # A Hash for serialization
64
95
  #
65
96
  # @return [Hash]
66
97
  def serializable_hash
67
- collection? ? @object.map(&converter) : converter.call(@object)
98
+ collection? ? serializable_hash_for_collection : converter.call(@object)
68
99
  end
69
100
  alias to_h serializable_hash
70
101
 
71
- # @deprecated Use {#serializable_hash} instead
72
- def to_hash
73
- warn '[DEPRECATION] `to_hash` is deprecated, use `serializable_hash` instead.'
74
- serializable_hash
75
- end
76
-
77
102
  private
78
103
 
79
- attr_reader :serialized_json # Mainly for layout
80
-
81
104
  def encode(hash)
82
105
  Alba.encoder.call(hash)
83
106
  end
84
107
 
108
+ def _to_json(root_key, meta, options)
109
+ options.reject! { |k, _| %i[layout prefixes template status].include?(k) } # Rails specific guard
110
+ # TODO: use `filter_map` after dropping support of Ruby 2.6
111
+ names = options.map { |k, v| k unless v.nil? }
112
+ names.compact!
113
+ unless names.empty?
114
+ names.sort!
115
+ names.map! { |s| "\"#{s}\"" }
116
+ message = "You passed #{names.join(', ')} options but ignored. Please refer to the document: https://github.com/okuramasafumi/alba/blob/main/docs/rails.md"
117
+ Kernel.warn(message)
118
+ end
119
+ serialize(root_key: root_key, meta: meta)
120
+ end
121
+
85
122
  def serialize_with(hash)
86
123
  serialized_json = encode(hash)
87
124
  return serialized_json unless @_layout
88
125
 
89
- @serialized_json = serialized_json
90
- if @_layout.is_a?(String) # file
91
- ERB.new(File.read(@_layout)).result(binding)
92
-
93
- else # inline
94
- serialize_within_inline_layout
95
- end
96
- end
97
-
98
- def serialize_within_inline_layout
99
- inline = instance_eval(&@_layout)
100
- case inline
101
- when Hash then encode(inline)
102
- when String then inline
103
- else
104
- raise Alba::Error, 'Inline layout must be a Proc returning a Hash or a String'
105
- end
126
+ @_layout.serialize(resource: self, serialized_json: serialized_json, binding: binding)
106
127
  end
107
128
 
108
129
  def hash_with_metadata(hash, meta)
@@ -113,130 +134,126 @@ module Alba
113
134
  hash
114
135
  end
115
136
 
137
+ def serializable_hash_for_collection
138
+ if @_collection_key
139
+ @object.to_h { |item| [item.public_send(@_collection_key).to_s, converter.call(item)] }
140
+ else
141
+ @object.each_with_object([], &collection_converter)
142
+ end
143
+ end
144
+
145
+ # @return [String]
116
146
  def fetch_key
117
- collection? ? _key_for_collection : _key
147
+ k = collection? ? _key_for_collection : _key
148
+ transforming_root_key? ? transform_key(k) : k
118
149
  end
119
150
 
120
151
  def _key_for_collection
121
- return @_key_for_collection.to_s unless @_key_for_collection == true && Alba.inferring
122
-
123
- key = resource_name.pluralize
124
- transforming_root_key? ? transform_key(key) : key
152
+ if Alba.inferring
153
+ @_key_for_collection == true ? resource_name(pluralized: true) : @_key_for_collection.to_s
154
+ else
155
+ @_key_for_collection == true ? raise_root_key_inference_error : @_key_for_collection.to_s
156
+ end
125
157
  end
126
158
 
127
159
  # @return [String]
128
160
  def _key
129
- return @_key.to_s unless @_key == true && Alba.inferring
161
+ if Alba.inferring
162
+ @_key == true ? resource_name(pluralized: false) : @_key.to_s
163
+ else
164
+ @_key == true ? raise_root_key_inference_error : @_key.to_s
165
+ end
166
+ end
130
167
 
131
- transforming_root_key? ? transform_key(resource_name) : resource_name
168
+ def resource_name(pluralized: false)
169
+ class_name = self.class.name
170
+ inflector = Alba.inflector
171
+ name = inflector.demodulize(class_name).delete_suffix('Resource')
172
+ underscore_name = inflector.underscore(name)
173
+ pluralized ? inflector.pluralize(underscore_name) : underscore_name
132
174
  end
133
175
 
134
- def resource_name
135
- @resource_name ||= self.class.name.demodulize.delete_suffix('Resource').underscore
176
+ def raise_root_key_inference_error
177
+ raise Alba::Error, 'You must call Alba.enable_inference! to set root_key to true for inferring root key.'
136
178
  end
137
179
 
138
180
  def transforming_root_key?
139
- @_transforming_root_key.nil? ? Alba.transforming_root_key : @_transforming_root_key
181
+ @_transforming_root_key
140
182
  end
141
183
 
142
- # rubocop:disable Metrics/MethodLength
143
184
  def converter
144
185
  lambda do |object|
145
- arrays = attributes.map do |key, attribute|
146
- key_and_attribute_body_from(object, key, attribute)
147
- rescue ::Alba::Error, FrozenError, TypeError
148
- raise
149
- rescue StandardError => e
150
- handle_error(e, object, key, attribute)
151
- end
152
- arrays.compact!
153
- arrays.to_h
186
+ attributes_to_hash(object, {})
154
187
  end
155
188
  end
156
- # rubocop:enable Metrics/MethodLength
157
189
 
158
- # This is default behavior for getting attributes for serialization
159
- # Override this method to filter certain attributes
160
- def attributes
161
- @_attributes
162
- end
163
-
164
- def key_and_attribute_body_from(object, key, attribute)
165
- key = transform_key(key)
166
- if attribute.is_a?(Array) # Conditional
167
- conditional_attribute(object, key, attribute)
168
- else
169
- fetched_attribute = fetch_attribute(object, key, attribute)
170
- [key, fetched_attribute]
190
+ def collection_converter
191
+ lambda do |object, a|
192
+ a << {}
193
+ h = a.last
194
+ attributes_to_hash(object, h)
195
+ a
171
196
  end
172
197
  end
173
198
 
174
- def conditional_attribute(object, key, attribute)
175
- condition = attribute.last
176
- if condition.is_a?(Proc)
177
- conditional_attribute_with_proc(object, key, attribute.first, condition)
178
- else
179
- conditional_attribute_with_symbol(object, key, attribute.first, condition)
199
+ def attributes_to_hash(object, hash)
200
+ attributes.each do |key, attribute|
201
+ set_key_and_attribute_body_from(object, key, attribute, hash)
202
+ rescue ::Alba::Error, FrozenError, TypeError
203
+ raise
204
+ rescue StandardError => e
205
+ handle_error(e, object, key, attribute, hash)
180
206
  end
207
+ hash
181
208
  end
182
209
 
183
- def conditional_attribute_with_proc(object, key, attribute, condition)
184
- arity = condition.arity
185
- # We can return early to skip fetch_attribute
186
- return if arity <= 1 && !instance_exec(object, &condition)
187
-
188
- fetched_attribute = fetch_attribute(object, key, attribute)
189
- attr = attribute.is_a?(Alba::Association) ? attribute.object : fetched_attribute
190
- return if arity >= 2 && !instance_exec(object, attr, &condition)
191
-
192
- [key, fetched_attribute]
210
+ # This is default behavior for getting attributes for serialization
211
+ # Override this method to filter certain attributes
212
+ def attributes
213
+ @_attributes
193
214
  end
194
215
 
195
- def conditional_attribute_with_symbol(object, key, attribute, condition)
196
- return unless __send__(condition)
197
-
198
- [key, fetch_attribute(object, key, attribute)]
216
+ def set_key_and_attribute_body_from(object, key, attribute, hash)
217
+ key = transform_key(key)
218
+ value = fetch_attribute(object, key, attribute)
219
+ hash[key] = value unless value == Alba::REMOVE_KEY
199
220
  end
200
221
 
201
- def handle_error(error, object, key, attribute)
202
- on_error = @_on_error || Alba._on_error
203
- case on_error
204
- when :raise, nil then raise
205
- when :nullify then [key, nil]
222
+ def handle_error(error, object, key, attribute, hash)
223
+ on_error = @_on_error || :raise
224
+ case on_error # rubocop:disable Style/MissingElse
225
+ when :raise, nil then raise(error)
226
+ when :nullify then hash[key] = nil
206
227
  when :ignore then nil
207
- when Proc then on_error.call(error, object, key, attribute, self.class)
208
- else
209
- raise ::Alba::Error, "Unknown on_error: #{on_error.inspect}"
228
+ when Proc
229
+ key, value = on_error.call(error, object, key, attribute, self.class)
230
+ hash[key] = value
210
231
  end
211
232
  end
212
233
 
213
- # rubocop:disable Metrics/MethodLength
214
234
  # @return [Symbol]
215
- def transform_key(key)
216
- return key if @_transform_type == :none
217
-
235
+ def transform_key(key) # rubocop:disable Metrics/CyclomaticComplexity
218
236
  key = key.to_s
219
- # TODO: Using default inflector here is for backward compatibility
220
- # From 2.0 it'll raise error when inflector is nil
221
- inflector = Alba.inflector || begin
222
- require_relative 'default_inflector'
223
- Alba::DefaultInflector
224
- end
237
+ return key if @_transform_type == :none || key.empty? # We can skip transformation
238
+
239
+ inflector = Alba.inflector
240
+ raise Alba::Error, 'Inflector is nil. You can set inflector with `Alba.enable_inference!(with: :active_support)` for example.' unless inflector
241
+
225
242
  case @_transform_type # rubocop:disable Style/MissingElse
226
243
  when :camel then inflector.camelize(key)
227
244
  when :lower_camel then inflector.camelize_lower(key)
228
245
  when :dash then inflector.dasherize(key)
229
246
  when :snake then inflector.underscore(key)
230
- end.to_sym
247
+ end
231
248
  end
232
- # rubocop:enable Metrics/MethodLength
233
249
 
234
- def fetch_attribute(object, key, attribute)
250
+ def fetch_attribute(object, key, attribute) # rubocop:disable Metrics/CyclomaticComplexity
235
251
  value = case attribute
236
252
  when Symbol then fetch_attribute_from_object_and_resource(object, attribute)
237
253
  when Proc then instance_exec(object, &attribute)
238
254
  when Alba::Association then yield_if_within(attribute.name.to_sym) { |within| attribute.to_h(object, params: params, within: within) }
239
- when TypedAttribute then attribute.value(object)
255
+ when TypedAttribute, NestedAttribute then attribute.value(object)
256
+ when ConditionalAttribute then attribute.with_passing_condition(resource: self, object: object) { |attr| fetch_attribute(object, key, attr) }
240
257
  else
241
258
  raise ::Alba::Error, "Unsupported type of attribute: #{attribute.class}"
242
259
  end
@@ -246,16 +263,16 @@ module Alba
246
263
  def fetch_attribute_from_object_and_resource(object, attribute)
247
264
  has_method = @method_existence[attribute]
248
265
  has_method = @method_existence[attribute] = object.respond_to?(attribute) if has_method.nil?
249
- has_method ? object.public_send(attribute) : __send__(attribute, object)
266
+ has_method ? object.__send__(attribute) : __send__(attribute, object)
250
267
  end
251
268
 
252
269
  def nil_handler
253
- @nil_handler ||= (@_on_nil || Alba._on_nil)
270
+ @_on_nil
254
271
  end
255
272
 
256
273
  def yield_if_within(association_name)
257
274
  within = check_within(association_name)
258
- yield(within) if within
275
+ within ? yield(within) : Alba::REMOVE_KEY
259
276
  end
260
277
 
261
278
  def check_within(association_name)
@@ -304,7 +321,7 @@ module Alba
304
321
 
305
322
  def assign_attributes(attrs, if_value)
306
323
  attrs.each do |attr_name|
307
- attr = if_value ? [attr_name.to_sym, if_value] : attr_name.to_sym
324
+ attr = if_value ? ConditionalAttribute.new(body: attr_name.to_sym, condition: if_value) : attr_name.to_sym
308
325
  @_attributes[attr_name.to_sym] = attr
309
326
  end
310
327
  end
@@ -315,7 +332,7 @@ module Alba
315
332
  attr_name = attr_name.to_sym
316
333
  type, type_converter = type_and_converter
317
334
  typed_attr = TypedAttribute.new(name: attr_name, type: type, converter: type_converter)
318
- attr = if_value ? [typed_attr, if_value] : typed_attr
335
+ attr = if_value ? ConditionalAttribute.new(body: typed_attr, condition: if_value) : typed_attr
319
336
  @_attributes[attr_name] = attr
320
337
  end
321
338
  end
@@ -332,38 +349,59 @@ module Alba
332
349
  def attribute(name, **options, &block)
333
350
  raise ArgumentError, 'No block given in attribute method' unless block
334
351
 
335
- @_attributes[name.to_sym] = options[:if] ? [block, options[:if]] : block
352
+ @_attributes[name.to_sym] = options[:if] ? ConditionalAttribute.new(body: block, condition: options[:if]) : block
336
353
  end
337
354
 
338
355
  # Set association
339
356
  #
340
357
  # @param name [String, Symbol] name of the association, used as key when `key` param doesn't exist
341
358
  # @param condition [Proc, nil] a Proc to modify the association
342
- # @param resource [Class<Alba::Resource>, String, nil] representing resource for this association
359
+ # @param resource [Class<Alba::Resource>, String, Proc, nil] representing resource for this association
343
360
  # @param key [String, Symbol, nil] used as key when given
361
+ # @param params [Hash] params override for the association
344
362
  # @param options [Hash<Symbol, Proc>]
345
363
  # @option options [Proc] if a condition to decide if this association should be serialized
346
364
  # @param block [Block]
347
365
  # @return [void]
348
366
  # @see Alba::Association#initialize
349
- def association(name, condition = nil, resource: nil, key: nil, **options, &block)
350
- nesting = self.name&.rpartition('::')&.first
351
- assoc = Association.new(name: name, condition: condition, resource: resource, nesting: nesting, &block)
352
- @_attributes[key&.to_sym || name.to_sym] = options[:if] ? [assoc, options[:if]] : assoc
367
+ def association(name, condition = nil, resource: nil, key: nil, params: {}, **options, &block)
368
+ key_transformation = @_key_transformation_cascade ? @_transform_type : :none
369
+ assoc = Association.new(
370
+ name: name, condition: condition, resource: resource, params: params, nesting: nesting, key_transformation: key_transformation,
371
+ &block
372
+ )
373
+ @_attributes[key&.to_sym || name.to_sym] = options[:if] ? ConditionalAttribute.new(body: assoc, condition: options[:if]) : assoc
353
374
  end
354
375
  alias one association
355
376
  alias many association
356
377
  alias has_one association
357
378
  alias has_many association
358
379
 
359
- # Set key
380
+ def nesting
381
+ if name.nil?
382
+ nil
383
+ else
384
+ name.rpartition('::').first.tap { |n| n.empty? ? nil : n }
385
+ end
386
+ end
387
+ private :nesting
388
+
389
+ # Set a nested attribute with the given block
360
390
  #
361
- # @param key [String, Symbol]
362
- # @deprecated Use {#root_key} instead
363
- def key(key)
364
- Alba::Deprecation.warn '[DEPRECATION] `key` is deprecated, use `root_key` instead.'
365
- @_key = key.respond_to?(:to_sym) ? key.to_sym : key
391
+ # @param name [String, Symbol] key name
392
+ # @param options [Hash<Symbol, Proc>]
393
+ # @option options [Proc] if a condition to decide if this attribute should be serialized
394
+ # @param block [Block] the block called during serialization
395
+ # @raise [ArgumentError] if block is absent
396
+ # @return [void]
397
+ def nested_attribute(name, **options, &block)
398
+ raise ArgumentError, 'No block given in attribute method' unless block
399
+
400
+ key_transformation = @_key_transformation_cascade ? @_transform_type : :none
401
+ attribute = NestedAttribute.new(key_transformation: key_transformation, &block)
402
+ @_attributes[name.to_sym] = options[:if] ? ConditionalAttribute.new(body: attribute, condition: options[:if]) : attribute
366
403
  end
404
+ alias nested nested_attribute
367
405
 
368
406
  # Set root key
369
407
  #
@@ -375,13 +413,13 @@ module Alba
375
413
  @_key_for_collection = key_for_collection&.to_sym
376
414
  end
377
415
 
378
- # Set key to true
416
+ # Set root key for collection
379
417
  #
380
- # @deprecated Use {#root_key!} instead
381
- def key!
382
- Alba::Deprecation.warn '[DEPRECATION] `key!` is deprecated, use `root_key!` instead.'
418
+ # @param key [String, Symbol]
419
+ # @raise [NoMethodError] when key doesn't respond to `to_sym` method
420
+ def root_key_for_collection(key)
383
421
  @_key = true
384
- @_key_for_collection = true
422
+ @_key_for_collection = key.to_sym
385
423
  end
386
424
 
387
425
  # Set root key to true
@@ -400,45 +438,17 @@ module Alba
400
438
  # @params file [String] name of the layout file
401
439
  # @params inline [Proc] a proc returning JSON string or a Hash representing JSON
402
440
  def layout(file: nil, inline: nil)
403
- @_layout = validated_file_layout(file) || validated_inline_layout(inline)
404
- end
405
-
406
- def validated_file_layout(filename)
407
- case filename
408
- when String, nil then filename
409
- else
410
- raise ArgumentError, 'File layout must be a String representing filename'
411
- end
412
- end
413
- private :validated_file_layout
414
-
415
- def validated_inline_layout(inline_layout)
416
- case inline_layout
417
- when Proc, nil then inline_layout
418
- else
419
- raise ArgumentError, 'Inline layout must be a Proc returning a Hash or a String'
420
- end
421
- end
422
- private :validated_inline_layout
423
-
424
- # Delete attributes
425
- # Use this DSL in child class to ignore certain attributes
426
- #
427
- # @param attributes [Array<String, Symbol>]
428
- def ignoring(*attributes)
429
- Alba::Deprecation.warn '`ignoring` is deprecated now. Instead please use `attributes` instance method to filter out attributes.'
430
- attributes.each do |attr_name|
431
- @_attributes.delete(attr_name.to_sym)
432
- end
441
+ @_layout = Layout.new(file: file, inline: inline)
433
442
  end
434
443
 
435
444
  # Transform keys as specified type
436
445
  #
437
446
  # @param type [String, Symbol] one of `snake`, `:camel`, `:lower_camel`, `:dash` and `none`
438
- # @param root [Boolean, nil] decides if root key also should be transformed
439
- # When it's `nil`, Alba's default setting will be applied
447
+ # @param root [Boolean] decides if root key also should be transformed
448
+ # @param cascade [Boolean] decides if key transformation cascades into inline association
449
+ # Default is true but can be set false for old (v1) behavior
440
450
  # @raise [Alba::Error] when type is not supported
441
- def transform_keys(type, root: nil)
451
+ def transform_keys(type, root: true, cascade: true)
442
452
  type = type.to_sym
443
453
  unless %i[none snake camel lower_camel dash].include?(type)
444
454
  # This should be `ArgumentError` but for backward compatibility it raises `Alba::Error`
@@ -447,6 +457,14 @@ module Alba
447
457
 
448
458
  @_transform_type = type
449
459
  @_transforming_root_key = root
460
+ @_key_transformation_cascade = cascade
461
+ end
462
+
463
+ # Sets key for collection serialization
464
+ #
465
+ # @param key [String, Symbol]
466
+ def collection_key(key)
467
+ @_collection_key = key.to_sym
450
468
  end
451
469
 
452
470
  # Set error handler
@@ -458,8 +476,19 @@ module Alba
458
476
  raise ArgumentError, 'You cannot specify error handler with both Symbol and block' if handler && block
459
477
  raise ArgumentError, 'You must specify error handler with either Symbol or block' unless handler || block
460
478
 
461
- @_on_error = handler || block
479
+ @_on_error = block || validated_error_handler(handler)
480
+ end
481
+
482
+ def validated_error_handler(handler)
483
+ unless %i[raise ignore nullify].include?(handler)
484
+ # For backward compatibility
485
+ # TODO: Change this to ArgumentError
486
+ raise Alba::Error, "Unknown error handler: #{handler}. It must be one of `:raise`, `:ignore` or `:nullify`."
487
+ end
488
+
489
+ handler
462
490
  end
491
+ private :validated_error_handler
463
492
 
464
493
  # Set nil handler
465
494
  #
@@ -26,7 +26,7 @@ module Alba
26
26
  private
27
27
 
28
28
  def check(object)
29
- value = object.public_send(@name)
29
+ value = object.__send__(@name)
30
30
  type_correct = case @type
31
31
  when :String, ->(klass) { klass == String } then value.is_a?(String)
32
32
  when :Integer, ->(klass) { klass == Integer } then value.is_a?(Integer)
data/lib/alba/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Alba
2
- VERSION = '1.6.0'.freeze
2
+ VERSION = '2.0.1'.freeze
3
3
  end