lib/avromatic/model/attributes.rb in avromatic-2.0.0 vs lib/avromatic/model/attributes.rb in avromatic-2.0.1
- old
+ new
@@ -19,18 +19,19 @@
super("Optional field not allowed: #{field}")
end
end
class AttributeDefinition
- attr_reader :name, :type, :field, :default, :owner
+ attr_reader :name, :setter_name, :type, :field, :default, :owner
delegate :serialize, to: :type
def initialize(owner:, field:, type:)
@owner = owner
@field = field
@type = type
@name = field.name.to_sym
+ @setter_name = "#{field.name}=".to_sym
@default = if field.default == :no_default
nil
elsif field.default.duplicable?
field.default.dup.deep_freeze
else
@@ -75,17 +76,17 @@
valid_keys = []
attribute_definitions.each do |attribute_name, attribute_definition|
if data.include?(attribute_name)
valid_keys << attribute_name
value = data.fetch(attribute_name)
- _attributes[attribute_name] = attribute_definition.coerce(value)
+ send(attribute_definition.setter_name, value)
elsif data.include?(attribute_name.to_s)
valid_keys << attribute_name
value = data[attribute_name.to_s]
- _attributes[attribute_name] = attribute_definition.coerce(value)
+ send(attribute_definition.setter_name, value)
elsif !attributes.include?(attribute_name)
- _attributes[attribute_name] = attribute_definition.default
+ send(attribute_definition.setter_name, attribute_definition.default)
end
end
unless Avromatic.allow_unknown_attributes || valid_keys.size == data.size
unknown_attributes = (data.keys.map(&:to_s) - valid_keys.map(&:to_s)).sort
@@ -109,25 +110,25 @@
def _attributes
@attributes ||= {}
end
module ClassMethods
- def add_avro_fields
+ def add_avro_fields(generated_methods_module)
# models are registered in Avromatic.nested_models at this point to
# ensure that they are available as fields for recursive models.
register!
if key_avro_schema
check_for_field_conflicts!
begin
- define_avro_attributes(key_avro_schema,
+ define_avro_attributes(key_avro_schema, generated_methods_module,
allow_optional: config.allow_optional_key_fields)
rescue OptionalFieldError => ex
raise "Optional field '#{ex.field.name}' not allowed in key schema."
end
end
- define_avro_attributes(avro_schema)
+ define_avro_attributes(avro_schema, generated_methods_module)
end
private
def check_for_field_conflicts!
@@ -149,11 +150,11 @@
def schema_fields_differ?(name)
key_avro_fields_by_name[name].to_avro !=
value_avro_fields_by_name[name].to_avro
end
- def define_avro_attributes(schema, allow_optional: true)
+ def define_avro_attributes(schema, generated_methods_module, allow_optional: true)
if schema.type_sym != :record
raise "Unsupported schema type '#{schema.type_sym}', only 'record' schemas are supported."
end
schema.fields.each do |field|
@@ -161,35 +162,27 @@
symbolized_field_name = field.name.to_sym
attribute_definition = AttributeDefinition.new(
owner: self,
field: field,
- type: create_type(field)
+ type: Avromatic::Model::Types::TypeFactory.create(schema: field.type, nested_models: nested_models)
)
attribute_definitions[symbolized_field_name] = attribute_definition
- define_method(field.name) { _attributes[symbolized_field_name] }
- define_method("#{field.name}?") { !!_attributes[symbolized_field_name] } if boolean?(field)
+ # Add all generated methods to a module so they can be overridden
+ generated_methods_module.send(:define_method, field.name) { _attributes[symbolized_field_name] }
+ generated_methods_module.send(:define_method, "#{field.name}?") { !!_attributes[symbolized_field_name] } if FieldHelper.boolean?(field)
- define_method("#{field.name}=") do |value|
+ generated_methods_module.send(:define_method, "#{field.name}=") do |value|
_attributes[symbolized_field_name] = attribute_definitions[symbolized_field_name].coerce(value)
end
unless config.mutable # rubocop:disable Style/Next
- private("#{field.name}=")
- define_method(:clone) { self }
- define_method(:dup) { self }
+ generated_methods_module.send(:private, "#{field.name}=")
+ generated_methods_module.send(:define_method, :clone) { self }
+ generated_methods_module.send(:define_method, :dup) { self }
end
end
- end
-
- def boolean?(field)
- field.type.type_sym == :boolean ||
- (FieldHelper.optional?(field) && field.type.schemas.last.type_sym == :boolean)
- end
-
- def create_type(field)
- Avromatic::Model::Types::TypeFactory.create(schema: field.type, nested_models: nested_models)
end
end
end
end