module Avromatic::Model::Attributes::ClassMethods

Public Instance Methods

add_avro_fields(generated_methods_module) click to toggle source
# File lib/avromatic/model/attributes.rb, line 141
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, generated_methods_module,
                             allow_optional: config.allow_optional_key_fields)
    rescue OptionalFieldError => e
      raise "Optional field '#{e.field.name}' not allowed in key schema."
    end
  end
  define_avro_attributes(avro_schema, generated_methods_module)
end
recursively_immutable?() click to toggle source
# File lib/avromatic/model/attributes.rb, line 158
def recursively_immutable?
  return @recursively_immutable if defined?(@recursively_immutable)

  @recursively_immutable = immutable? && attribute_definitions.each_value.all?(&:values_immutable?)
end

Private Instance Methods

check_for_field_conflicts!() click to toggle source
# File lib/avromatic/model/attributes.rb, line 166
def check_for_field_conflicts!
  conflicts =
    (key_avro_field_names & value_avro_field_names).each_with_object([]) do |name, msgs|
      next unless schema_fields_differ?(name)

      msgs << "Field '#{name}' has a different type in each schema: "\
              "value #{value_avro_fields_by_name[name]}, "\
              "key #{key_avro_fields_by_name[name]}"
    end

  raise conflicts.join("\n") if conflicts.any?

  conflicts
end
define_avro_attributes(schema, generated_methods_module, allow_optional: true) click to toggle source
# File lib/avromatic/model/attributes.rb, line 188
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|
    raise OptionalFieldError.new(field) if !allow_optional && FieldHelper.optional?(field)

    symbolized_field_name = field.name.to_sym
    attribute_definition = AttributeDefinition.new(
      owner: self,
      field: field,
      type: Avromatic::Model::Types::TypeFactory.create(schema: field.type, nested_models: nested_models)
    )
    attribute_definitions[symbolized_field_name] = attribute_definition

    # Add all generated methods to a module so they can be overridden
    generated_methods_module.send(:define_method, field.name) { _attributes[symbolized_field_name] }
    if FieldHelper.boolean?(field)
      generated_methods_module.send(:define_method, "#{field.name}?") do
        !!_attributes[symbolized_field_name]
      end
    end

    generated_methods_module.send(:define_method, "#{field.name}=") do |value|
      _attributes[symbolized_field_name] = attribute_definition.coerce(value)
    end

    unless mutable? # rubocop:disable Style/Next
      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
schema_fields_differ?(name) click to toggle source

The Avro::Schema::Field#== method is lame. It just compares <field>.type.type_sym.

# File lib/avromatic/model/attributes.rb, line 183
def schema_fields_differ?(name)
  key_avro_fields_by_name[name].to_avro !=
    value_avro_fields_by_name[name].to_avro
end