parent
c3fa27dcc7
commit
e847e8c409
|
@ -38,20 +38,28 @@ puts errors.to_h.inspect
|
|||
# }
|
||||
```
|
||||
|
||||
It is equivalent to call `value` macro with `:hash` predicate and a block:
|
||||
|
||||
```ruby
|
||||
schema = Dry::Schema.Params do
|
||||
required(:address).value(:hash) do
|
||||
# ...
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Nested Maybe `Hash`
|
||||
|
||||
If a nested hash could be `nil`, simply use `maybe` macro with a block:
|
||||
|
||||
```ruby
|
||||
schema = Dry::Schema.Params do
|
||||
required(:address).maybe do
|
||||
hash do
|
||||
required(:city).filled(:string, min_size?: 3)
|
||||
required(:street).filled(:string)
|
||||
required(:country).hash do
|
||||
required(:name).filled(:string)
|
||||
required(:code).filled(:string)
|
||||
end
|
||||
required(:address).maybe(:hash) do
|
||||
required(:city).filled(:string, min_size?: 3)
|
||||
required(:street).filled(:string)
|
||||
required(:country).hash do
|
||||
required(:name).filled(:string)
|
||||
required(:code).filled(:string)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,13 +27,18 @@ module Dry
|
|||
end
|
||||
|
||||
trace.evaluate(*predicates, **opts)
|
||||
trace.append(new(chain: false).instance_exec(&block)) if block
|
||||
|
||||
type_spec = opts[:type_spec]
|
||||
if block && type_spec.equal?(:hash)
|
||||
hash(&block)
|
||||
elsif block
|
||||
trace.append(new(chain: false).instance_exec(&block))
|
||||
end
|
||||
|
||||
if trace.captures.empty?
|
||||
raise ArgumentError, 'wrong number of arguments (given 0, expected at least 1)'
|
||||
end
|
||||
|
||||
type_spec = opts[:type_spec]
|
||||
each(type_spec.type.member) if type_spec.respond_to?(:member)
|
||||
|
||||
self
|
||||
|
|
|
@ -110,5 +110,33 @@ RSpec.describe 'Macros #maybe' do
|
|||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a nested hash' do
|
||||
subject(:schema) do
|
||||
Dry::Schema.define do
|
||||
required(:song).maybe(:hash) do
|
||||
required(:title).filled
|
||||
required(:author).filled
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'passes when valid' do
|
||||
song = { title: 'World', author: 'Joe' }
|
||||
|
||||
expect(schema.(song: song)).to be_success
|
||||
end
|
||||
|
||||
it 'fails when not valid' do
|
||||
song = { title: nil, author: 'Jane' }
|
||||
|
||||
expect(schema.(song: song).messages).to eql(
|
||||
song: { title: ['must be filled'] }
|
||||
)
|
||||
end
|
||||
|
||||
it 'passes when nil' do
|
||||
expect(schema.(song: nil)).to be_success
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,4 +31,29 @@ RSpec.describe Dry::Schema::Macros::Value do
|
|||
expect { macro.not_here }.to raise_error(NoMethodError, /not_here/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a nested hash' do
|
||||
subject(:schema) do
|
||||
Dry::Schema.define do
|
||||
required(:song).value(:hash) do
|
||||
required(:title).filled
|
||||
required(:author).filled
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'passes when valid' do
|
||||
song = { title: 'World', author: 'Joe' }
|
||||
|
||||
expect(schema.(song: song)).to be_success
|
||||
end
|
||||
|
||||
it 'fails when not valid' do
|
||||
song = { title: nil, author: 'Jane' }
|
||||
|
||||
expect(schema.(song: song).messages).to eql(
|
||||
song: { title: ['must be filled'] }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue