Table of Contents
General
Models created during deserialization can access their immediate parent and the document root via two special accessors:
-
__parent:: The direct parent model instance -
__root:: The top-level/root model instance
These accessors are automatically assigned during deserialization, enabling nested child models to reference their context within the model hierarchy.
root via two special accessors added:
-
__parent:: The direct parent model instance -
__root:: The top-level/root model instance
These are assigned during deserialization so nested child models can reference context.
class Tag < Lutaml::Model::Serializable
attribute :text, :string
xml do
root "Tag"
map_content to: :text
end
key_value do
map "text", to: :text
end
end
class Tags < Lutaml::Model::Serializable
attribute :tag, Tag, collection: true
xml do
root "Tags"
map_element "Tag", to: :tag
end
key_value do
map "Tag", to: :tag
end
end
class Post < Lutaml::Model::Serializable
attribute :tags, Tags, collection: true
xml do
root "Post"
map_element "Tags", to: :tags
end
key_value do
map "Tags", to: :tags
end
end
post = Post.from_xml(<<~XML)
<Post>
<Tags>
<Tag>ruby</Tag>
<Tag>coding</Tag>
</Tags>
<Tags>
<Tag>JSON</Tag>
<Tag>coding</Tag>
</Tags>
</Post>
XML
first_tag = post.tags.first.tag.first # #<Tag:0x00000002e661a650 @text="ruby">
first_tag.__parent # #<Tags:0x00000002e5e90010 @tag=[#<Tag:0x00000002e5e5bb80 @text="ruby">, #<Tag:0x00000002e5e58ca0 @text="coding">]>
first_tag.__root # should return the `post` object
# Key-value formats also set these accessors
yaml = {
"Tags" => [
{
"Tag" => [
{ "text" => "ruby" },
{ "text" => "coding"}
]
},
{
"Tag" => [
{ "text" => "JSON" },
{ "text" => "coding" }
]
}
]
}.to_yaml
post2 = Post.from_yaml(yaml)
# Same as explained in XML `post` example
post2.tags.first.__parent
post2.tags.first.__root| If you manually instantiate models, you can set these accessors yourself if needed: |
child.__parent = parent
child.__root = parent.__root || parent