These are chat archives for dry-rb/chat

Aug 2017
Aaron Barthel
Aug 10 2017 16:12 UTC
@binarypaladin try something like this to clean up :company?
required(:type, :string)
  .filled(:str?, :entity_type?)
  .when(:company?) { value(:contact_name).str? ^ value(:executive_name).str? }
  .when(:person?) { value(:date_of_birth).date? }
Joshua Hansen
Aug 10 2017 19:21 UTC

@abrthel I'll try that. I don't know exactly how that resolves but if they were both true the total result will be false won't it? I feel like there needs an operator that says, "Just do it all and if anything in here is false return false, but don't halt execution." + was what I was considering if I added my own extension for the time being. Although I am going to wait and see how much I actually need it. Basically, I want something to nicely make conditional validations work like the top level validations. Everything in requiredand optional gets validated. Unless I'm missing something, that can't happen in a when or rule block.

I did some refactoring last night and it came together nicely though, in terms of strict vs. loose. In the "loose" schema I just use optional and maybe together to set the rules I want for if a value is present. Then I do this in my strict schema:

strict_schema = Dry::Validation.Schema(loose_schema) do
  %i[att1 att2 att3].each { |att| rule(att => [att], &:filled?) }

And I add other rules for conditionals if they're conditionally required to be filled.

Aaron Barthel
Aug 10 2017 19:39 UTC
@binarypaladin > "Just do it all and if anything in here is false return false, but don't halt execution."
The ^ symbol in dry-validation means and/or so it should get you what you're looking for assuming I'm not totally misinterpreting what you're saying. The test spec for XOR
Joshua Hansen
Aug 10 2017 19:54 UTC

@abrthel In the example, if both .eql? validations return true it results in an error for be_reasonable. If one of them is true and the other is false you end up with a pass. So, value(:contact_name).str? ^ value(:executive_name).str? will certainly always evaluate both, but if both are true the rule as a whole will result in a failure. What I want is & functionality without short circuiting.

I can get the results I want though, it just requires more rules than I think it should but... I also don't know how often I'm going to do this. A non-ideal solution is fine for now. I'll try hacking in a + operator or something later. It'd be a good exercise if nothing else.