Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
Sam Starling
@samstarling
I tried something like this, but it didn't work:
required(:type).filled.when(:true?) do
  value(:amount).filled(:number?)
end

And also this:

required(:type).filled
optional(:amount).filled

rule(amount_present: [:type, :amount]) do |type, amount|
  type.eql?('DEPOSIT') > amount.filled? > amount.number?
end

But that doesn't fail when the type is DEPOSIT and amount is excluded. So I probably misunderstood something somewhere :)

Gustavo Caso
@GustavoCaso
Could you paste your schema?
Sam Starling
@samstarling
Sure:
TransactionSchema = Dry::Validation.Form do
  required(:type).filled
  optional(:amount).filled(:number?)
  rule(amount_present: [:type, :amount]) do |type, amount|
    type.eql?('DEPOSIT') > amount.filled? > amount.number?
  end
end
Roland Laurès
@ShamoX
Hi, I'm using dry-validator on complexe structures with nested data inside Arrays. I wanted to know if it's possible to get the array index of a failing rule ? Isn't it be a good feature if it doesn't exist ? (worth an issue ? :D )
In fact getting the whole errors trace each time, would be great.
Gustavo Caso
@GustavoCaso
@samstarling I have this script working
So if the type is DEPOSIT the amount must be present
I'm not a heavy user of dry-validations so I do not know if it is the best way to achieve it
require 'bundler/inline'

gemfile true do
  source 'https://rubygems.org'
  gem 'dry-validation'
  gem 'pry'
end

TransactionSchema = Dry::Validation.Form do
  configure do
    def self.messages
      super.merge(en: { errors: { amount_present: 'if type is DEPOSIT amount must be present' }})
    end
  end

  required(:type).filled
  optional(:amount).filled(:number?)

  validate(amount_present: [:type, :amount]) do |type, amount|
    if type.eql?('DEPOSIT')
      !amount.nil?
    else
      true
    end
  end
end

payload = {
  'type' => 'DEPOSIT'
}

payload2 = {
  'type' => 'OTHER'
}


result = TransactionSchema.call(payload)
puts result.success? # => false
puts result.errors # => {:amount_present=>["if type is DEPOSIT amount must be present"]}

result2 = TransactionSchema.call(payload2)
puts result2.success? # => true
puts result2.errors # => {}
Gustavo Caso
@GustavoCaso
@ShamoX doesn't each macro or schema provide the index of it
Sam Starling
@samstarling
@GustavoCaso Ah OK, thanks! Let me check that :)
Roland Laurès
@ShamoX
@GustavoCaso This is what I expected, but it seems I'm in a case where the schema validation inside my each is not called... I'm still investigated. Then I guess my call was prematurate.
Gustavo Caso
@GustavoCaso
@samstarling let me know if it helps
Same @ShamoX
Roland Laurès
@ShamoX
yes, thanks.
Roland Laurès
@ShamoX
@GustavoCaso is this working with the Dry::Validation.Form constructor ? Because this is what I use. I don't use Schema like in the example. Also I'm using an existing Schema (also made with Form), is that a problem ?
I'll try to make a short example where I reproduce the bug (or find my error)
Gustavo Caso
@GustavoCaso
Great share when you have it
ojab
@ojab
float = Dry::Types['coercible.float'].constrained(gteq: 0).constructor do |input|
  input == :x ? 1.0 : input
end

float2 = Dry::Types['coercible.float'].constructor do |input|
  input == :x ? 1.0 : input
end

float[:x] # => 1.0
float2[:x] # => `Float': can't convert Symbol into Float (TypeError)
is it a bug or a feature and why behaviour differs? dry-types-0.13.0 here.
ojab
@ojab
 Dry::Types['bool'].enum('true' => true)['true']
# => Dry::Types::ConstraintError ("true" violates constraints ("true" must be an instance of FalseClass failed))
hmm..
Gustavo Caso
@GustavoCaso
@ojab Dry::Types['string'].enum('true' => true)['true'] # => true
ojab
@ojab
ouch
._.
my bad, thanks
Gustavo Caso
@GustavoCaso
No problem
happy to help
ojab
@ojab
hmm, actually it returns 'true' instead of true
Gustavo Caso
@GustavoCaso
hmm actually it is
Gustavo Caso
@GustavoCaso
checking code
ojab
@ojab
also looks like 'bool' doesn't propertly handle .constructor:
bool = Dry::Types['bool'].constructor { |input| input }
p bool.valid?(true)
# => undefined method `primitive' for #<Dry::Types::Sum:0x0000000001fd1500> (NoMethodError)
# Did you mean?  primitive?
Gustavo Caso
@GustavoCaso
Ok so for Enum is the expected behaviour based on the specs
spec following your example:
context 'with hash value' do
    subject(:enum) { Dry::Types['string'].enum('true' => true, 'false' => false) }

    it 'allows defining an enum from a specific type' do
      expect(enum['true']).to eql('true')
      expect(enum['false']).to eql('false')
      expect(enum[true]).to eql('true')
      expect(enum[false]).to eql('false')
    end
  end
The type Dry::Types['string'] is for making sure the keys are from that specific type
ojab
@ojab
So enum returning Boolean is not possible by design or Dry::Types['bool'] in theory should work?
Gustavo Caso
@GustavoCaso
That would require the keys being bool
let me check
Dry::Types['bool'].enum(true => 'true')['true']
# => true
Dry::Types['bool'].enum(true => 'true')[true]
# => true
ojab
@ojab
looks like it actually mapping values to keys, not vise-a-versa, so it's impossible to create mappings to boolean values :/
looks like the proper way to map values to Booleans is constructor, but we can't check .valid? in that case
Gustavo Caso
@GustavoCaso
What are you trying to achieve could you paste the code?
ojab
@ojab
I'm trying to spec some code that does the same as Coercions::Params for bool with different BOOLEAN_MAP and the issue is specs:
    subject(:valid?) do
      begin
        coerced = described_class[input]
        described_class.valid?(coerced)
      rescue Dry::Types::ConstraintError
        false
      end
    end
and valid? fails with undefined method 'primitive'
I can compare it with expected value of course, but it's not so intuitive IMO
and also what if returned value is expected, but invalid itself because I wrote a shitty test?
Nikita Shilnikov
@flash-gordon
it's a legitimate case to have a constructor on top of sum, so looks like a bug to me