# \[Dry-Struct\] How to create a nested struct in an optional array?

**URL:** <https://discourse.dry-rb.org/t/dry-struct-how-to-create-a-nested-struct-in-an-optional-array/1810>\
**Category:** Support\
**Created:** [July 10, 2024, 12:00am UTC](https://discourse.dry-rb.org/t/dry-struct-how-to-create-a-nested-struct-in-an-optional-array/1810 "2024-07-10T00:00:04Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![BonMatts](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/bonmatts/32/978_2.png) [@BonMatts](https://discourse.dry-rb.org/u/BonMatts)\
**Post date:** [July 10, 2024, 12:00am UTC](https://discourse.dry-rb.org/t/dry-struct-how-to-create-a-nested-struct-in-an-optional-array/1810/1 "2024-07-10T00:00:04Z")

</div>

I’m trying to create an attrbute that is an optional array with a nested struct.  
I’ve tried

```auto
attribute :someArray, Types::Array.of(
Dry::Schema.optional do
  attribute :someString, Types::String
attribute :someInteger, Types::Integer
).optional

```

But that results in an array of empty hashes. What is the correct way to do this?  
Thank you for your help!

---

<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:** [July 10, 2024, 7:38pm UTC](https://discourse.dry-rb.org/t/dry-struct-how-to-create-a-nested-struct-in-an-optional-array/1810/2 "2024-07-10T19:38:30Z")

</div>

What part of this do you want to be optional? An array type allows itself to be empty unless you constrain it with `min_size`.

If you want _the key itself_ to be optional, declare it with `attribute?`

```ruby
attribute? :someArray, Types::Array.default { [] } do
  attribute :someString, Types::String
  attribute :someInteger, Types::Integer
end

```

---

<div class="post-metadata">

**Author:** ![BonMatts](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/bonmatts/32/978_2.png) [@BonMatts](https://discourse.dry-rb.org/u/BonMatts)\
**Post date:** [July 10, 2024, 9:09pm UTC](https://discourse.dry-rb.org/t/dry-struct-how-to-create-a-nested-struct-in-an-optional-array/1810/4 "2024-07-10T21:09:43Z")

</div>

I do not want the key to be optional, I want the value of the array to be optional. The value of the array can be nil or it can be an array of structs.

---

<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:** [July 10, 2024, 10:08pm UTC](https://discourse.dry-rb.org/t/dry-struct-how-to-create-a-nested-struct-in-an-optional-array/1810/5 "2024-07-10T22:08:35Z")

</div>

Explicitly passing `nil` is a little trickier, since it doesn’t seem to be compatible with inline nesting. But you can achieve that by decomposing the nested struct.

```ruby
class Thing < Dry::Struct
  attribute :someString, Types::String
  attribute :someInteger, Types::Integer
end

class Test < Dry::Struct
  attribute :someArray, Types::Array.of(Thing).optional
end

```

```auto
[1] pry(main)> Test.new
Dry::Struct::Error: [Test.new] :someArray is missing in Hash input
[2] pry(main)> Test.new({ someArray: nil })
=> #<Test someArray=nil>
[3] pry(main)> Test.new({ someArray: [] })
=> #<Test someArray=[]>
[4] pry(main)> Test.new({ someArray: [{}] })
Dry::Struct::Error: [Thing.new] :someString is missing in Hash input
[5] pry(main)> Test.new({ someArray: [{ someString: 'foo', someInteger: 123 }] })
=> #<Test someArray=[#<Thing someString="foo" someInteger=123>]>

```
