Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested Records are Not Instantiated #116

Open
dacohen opened this issue Aug 28, 2019 · 2 comments
Open

Nested Records are Not Instantiated #116

dacohen opened this issue Aug 28, 2019 · 2 comments

Comments

@dacohen
Copy link

dacohen commented Aug 28, 2019

When I define an Avromatic class, and instantiate it, I expect all the nested records to also be instantiated. Instead, only the top-most record is instantiated, and any sub-records are nil.

Here's a simple reproduction:

Avro Schema:

{
  "type": "record",
  "name": "top_rec",
  "namespace": "com.example",
  "fields": [
    {
      "name": "sub",
      "type": {
        "type": "record",
        "name": "sub_rec",
        "namespace": "com.example",
        "fields": [
          {
            "name": "i",
            "type": "int"
          }
        ]
      }
    }
  ]
}

Then we load the schema and create a class:

schema_file = File.read('top_rec.avsc')
schema = Avro::Schema.parse(schema_file)

nestedClass = Avromatic::Model.model(schema: schema)

myClass = nestedClass.new
puts myClass.inspect

Actual Result:

#<TopRec sub: nil>

Expected Result:

#<TopRec sub: #<SubRec i: nil>>

Obviously, it's possible to manually instantiate the entire class hierarchy, but this quickly becomes difficult as the level of nesting increases.

@re-freitas
Copy link

re-freitas commented Nov 30, 2022

I am having the same issue, did you find a work around?

@jturkel
Copy link
Member

jturkel commented Dec 2, 2022

Sorry. We don't have a fix yet, mainly because we've moved to creating immutable models by default for performance reasons and this defaulting is likely to result in a model tree that's invalid and can't be made valid. I definitely see how it could be useful when dealing with mutable models though. In the meantime, you could workaround it via something like:

module ModelNestedRecordDefaulting
  EMPTY_HASH = {}.freeze

  def initialize(...)
    super

    attribute_definitions.each do |attribute_name, attribute_definition|
      if attribute_definition.type.is_a?(Avromatic::Model::Types::RecordType) && send(attribute_name).nil?
        send(attribute_definition.setter_name, EMPTY_HASH)
      end
    end
  end
end

# Include it in specific models
Avromatic::Model.model(schema: schema).include(ModelNestedRecordDefaulting)

# Alternatively patch it in globally for all models
module BuilderInclusionsPatch
  def inclusions
    super + [ModelNestedRecordDefaulting]
  end
end
Avromatic::Model::Builder.prepend(BuilderInclusionsPatch)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants