# Nested dry-struct serialization

**URL:** <https://discourse.dry-rb.org/t/nested-dry-struct-serialization/1722>\
**Category:** Support\
**Created:** [September 4, 2023, 5:51pm UTC](https://discourse.dry-rb.org/t/nested-dry-struct-serialization/1722 "2023-09-04T17:51:00Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dorner](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/dorner/32/913_2.png) [@dorner](https://discourse.dry-rb.org/u/dorner)\
**Post date:** [September 4, 2023, 5:51pm UTC](https://discourse.dry-rb.org/t/nested-dry-struct-serialization/1722/1 "2023-09-04T17:51:00Z")

</div>

Hi! Ultimately what I’m trying to do here is implement ActiveRecord serialization for dry-struct, as mentioned here: [dry-struct and serializer](https://discourse.dry-rb.org/t/dry-struct-and-serializer/1517)

I have a struct with reference to another struct, as follows:

```auto
  class InventoryPayload < Dry::Struct
     attribute :items, Types::Array.of(Types.Instance(EventTypes::EventLineItem))
  end

  class EventLineItem < Dry::Struct
    transform_keys(&:to_sym)
    attribute :item_id, Types::Integer
    attribute :item_value_in_cents, Types::Integer
  end

```

When this is dumped to a hash, the initialization logic doesn’t seem to have a good way to turn the nested part of the hash back into a struct:

```auto
irb> EventTypes::InventoryPayload.new(items: [{item_id: 1, item_value_in_cents: 1}])
Dry::Struct::Error: [EventTypes::InventoryPayload.new] [{:item_id=>1, :item_value_in_cents=>1}] (Array) has invalid type for :items violates constraints (type?(EventTypes::EventLineItem, {:item_id=>1, :item_value_in_cents=>1}) failed)

```

The only thing I was able to get working is to add a method `InventoryPayload` that maps the input hash to `EventLineItem`s. But this seems kind of odd - there should be some way to automatically coerce this? If not, that’s fine, but I’m wondering if I’m missing something.

---

<div class="post-metadata">

**Author:** ![alassek](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/alassek/32/314_2.png) [@alassek](https://discourse.dry-rb.org/u/alassek)\
**Post date:** [September 5, 2023, 4:24pm UTC](https://discourse.dry-rb.org/t/nested-dry-struct-serialization/1722/2 "2023-09-05T16:24:36Z")

</div>

`Types.Instance` is the problem here. The hash input will fail this check, what you want is a coercible type that will transform a hash into the struct. This is, in fact, how struct objects behave when you use them as types.

```ruby
class InventoryPayload < Dry::Struct
  attribute :items, Types::Array.of(EventLineItem)
end

```

```auto
[1] pry(main)> event = InventoryPayload.new(items: [{ item_id: 1, item_value_in_cents: 1 }])
=> #<InventoryPayload items=[#<EventLineItem item_id=1 item_value_in_cents=1>]>
[2] pry(main)> InventoryPayload.new(event.to_hash)
=> #<InventoryPayload items=[#<EventLineItem item_id=1 item_value_in_cents=1>]>

```

---

<div class="post-metadata">

**Author:** ![dorner](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/dorner/32/913_2.png) [@dorner](https://discourse.dry-rb.org/u/dorner)\
**Post date:** [September 5, 2023, 6:16pm UTC](https://discourse.dry-rb.org/t/nested-dry-struct-serialization/1722/3 "2023-09-05T18:16:25Z")

</div>

Ahhh there it is! The docs didn’t show this pattern so I wasn’t aware it was an option. Thanks!
