These are chat archives for dry-rb/chat

6th
Feb 2017
Jonah
@jonahx
Feb 06 2017 20:04 UTC
I’m trying to create a custom form validation. I got the validation part working but not sure how to customize the coercion part automatically. Here’s what I have so far:
schema = Dry::Validation.Form do
  configure do
    def future_date?(value)
      Date.new < Date.parse(value)
    end
  end
  required(:date).filled(:future_date?)
end
Piotr Solnica
@solnic
Feb 06 2017 20:05 UTC
@jonahx filled(:date?, :future_date?)
Jonah
@jonahx
Feb 06 2017 20:05 UTC
@solnic ah, so simple. ty sir!
@solnic but say i needed to coerce to some custom object, MyCustomObj. is this easily possible too?
Piotr Solnica
@solnic
Feb 06 2017 20:08 UTC
@jonahx why?
Jonah
@jonahx
Feb 06 2017 20:09 UTC
@solnic, i’m not sure i understand the question. why do you coerce into built-in ruby objects like Date or Integer?
Piotr Solnica
@solnic
Feb 06 2017 20:09 UTC
why you want to coerce to a custom object :)
Jonah
@jonahx
Feb 06 2017 20:12 UTC
i’ll make an example, since my current example the above works well :). but say user enters a hex value for a color into a form. i want to validate it’s a valid hex value and coerce into a custom Color object that has some nice methods for working with colors, say.
Piotr Solnica
@solnic
Feb 06 2017 20:15 UTC
do you need a color object for something else than the validation?
Jonah
@jonahx
Feb 06 2017 20:17 UTC
yeah the “domain” code that uses the params is what would use it. So no, the Color wouldn’t be used within the validation.
Piotr Solnica
@solnic
Feb 06 2017 20:18 UTC
@jonahx you can do this for more control http://dry-rb.org/gems/dry-validation/input-preprocessing/
explicit type specs will be default API in 1.0.0 btw
Jonah
@jonahx
Feb 06 2017 20:26 UTC
@solnic thx for link i will reread that part. one more quick question is there a quick way to define error messages without going through a custom yaml file? eg, in this case i only need to define a single error message for this one custom future_date? method and i’d prefer to define it in code near where future_date itself is defined
I guess we should document this
Jonah
@jonahx
Feb 06 2017 20:40 UTC
@solnic cool, ty. i was just in the midst of using pry to try to figure that out :), you saved me some minutes. i’d even recommend a chrome method over that , but that might be a micro-optimization
Jonah
@jonahx
Feb 06 2017 20:52 UTC
@solnic I’m getting an uninitialized constanct Messages error:
schema = Dry::Validation.Form do
  configure do
    def future_date?(value)
      Date.today < value
    end
    def self.messages
      Messages.default.merge(
        en: { errors: { future_date?: 'Date must be in the future' } }
      )
    end
  end
  required(:date).filled(:date?, :future_date?)
end
i thought it was because i was in Form instead of Schema but Schema isn’t working for me either...
Jonah
@jonahx
Feb 06 2017 21:36 UTC
@solnic finally got it working. not sure if it’s the best way or why the way in your spec didn’t work for me, but the following works:
schema = Dry::Validation.Form do
  configure do
    def future_date?(value)
      Date.today < value
    end
    def self.messages
      default_messages.merge(
        en: { errors: { future_date?: 'Date must be in the future' } }
      )
    end
  end
  required(:date).filled(:date?, :future_date?)
end
Piotr Solnica
@solnic
Feb 06 2017 21:59 UTC
@jonahx IIRC we have include Dry::Validation in spec_helper there heh
which is probably a stupid idea
Jonah
@jonahx
Feb 06 2017 22:00 UTC
@solnic do i have the Piotr stamp of approval on what I did above? :)
Piotr Solnica
@solnic
Feb 06 2017 22:01 UTC
@jonahx does it work? :D
Jonah
@jonahx
Feb 06 2017 22:02 UTC
@solnic it does! i think it would be better to merge on messages rather than default_messages, but you get infinite recursion doing that...
Piotr Solnica
@solnic
Feb 06 2017 22:03 UTC
it’s tricky stuff
defo a focus for 1.0.0
(to improve it)
Jonah
@jonahx
Feb 06 2017 22:03 UTC
ok thx. for my immediate purposes this is totally fine, so nbd
Piotr Solnica
@solnic
Feb 06 2017 22:04 UTC
cool
I’m not a fan of defining user-facing things in code, hence I didn’t add any nice way of defining custom messages inside code
it’s possible, but I don’t like it
I get that people often just need the quick’n’dirty solution though
and adding a special yaml file is not always desirable
I just didn’t have the need for a different approach than a yaml file because my context has been always an app with locales, where I keep dry-v’s messages
Jonah
@jonahx
Feb 06 2017 22:05 UTC
@solnic fair enough. i agree in most apps of any size at all a yaml file is a better way to go. i just happen to making literally a single page form tool
Piotr Solnica
@solnic
Feb 06 2017 22:05 UTC
sure thing, I’m not against it, so if somebody can make it better, then great
fwiw hanami-validation has a way of defining messages along with a predicate definition
IIRC sth like predicate(:foo?, message: “oh noez”) do.. end
Jonah
@jonahx
Feb 06 2017 22:06 UTC
@solnic meh, i prefer your tools :)
Piotr Solnica
@solnic
Feb 06 2017 22:06 UTC
it’s based on dry-v (as its validation engine)
but thanks :D
Jonah
@jonahx
Feb 06 2017 23:16 UTC
@solnic can you set the Error message when a Dry::Types constraint fails?
Piotr Solnica
@solnic
Feb 06 2017 23:30 UTC
@jonahx no, constraints != validation
Jonah
@jonahx
Feb 06 2017 23:34 UTC
@solnic if i define a custom email type, which say just requires an @ symbol, why wouldn’t you want to be able to throw a custom message if someone tries to create an instance with bad data: “An email just have an ‘@‘ symbol”. How is that not an improvement upon a generic message about a contraint violation or whatnot?
Piotr Solnica
@solnic
Feb 06 2017 23:42 UTC
@jonahx custom type constraints have different semantics than validation, they crash your system when something is invalid, validation is meant to process whole input and provide information about what validation rule violations.
Jonah
@jonahx
Feb 06 2017 23:47 UTC
@solnic right, i understand that. but shouldn’t i be able to define an email type, which raises errors, so that the type itself reflects my contraints, so that’s impossible to have in invalid Email type, and then, if i want, define my validation using that logic, yet without repeating that logic. that is, a validator which catches the InvalidEmail or whatever it raises, and the processes that as it sees fit. otherwise, aren’t you either 1. duplicating the logic in your type in your validator or 2. breaking apart your type so that the type itself does not contain its own constraints. If i’m missing an alternative please lmk
Piotr Solnica
@solnic
Feb 06 2017 23:49 UTC
oh dry-v actually extracts constraints from constrained types and use them as predicates, so there are no exceptions raised at all, and you can just define your messages. I specifically added this feature so that folks can share constraints between types and validation schemas
so ie you can have Types::Strict::String.constrained(format: /email-regex/) and then add a custom message for format? rule failure
Jonah
@jonahx
Feb 06 2017 23:54 UTC
@solnic so to use an example from the docs I define a custom email type Email = String.constrained(format: /@/). So 2 independent questions: 1. How can I, in my validator, catch specifically a failure of the Email type and create a custom error message for that? 2. I’d still like a custom error in the Email type itself, just in case, eg, I am using the type in a non-validation situation, and eg, hardcode an email in my constructor but mistype ‘me#gmail.com’ instead of ‘me@gmail.com’, when i run the code it would be nice to have a specific error message vs a general statement about constraints
ie, i see the ability to attach custom error messages to custom types as a totally independent question from the semantic difference between validations and constraints
Piotr Solnica
@solnic
Feb 06 2017 23:57 UTC
that would be a big addition, not sure if it’s worth the effort tbf :/
Jonah
@jonahx
Feb 06 2017 23:58 UTC
are you referring to just question 2. or to 1. as well?
Piotr Solnica
@solnic
Feb 06 2017 23:58 UTC
referring to custom exception messages
re question 1. you can’t catch a specific exception from a specific type because exceptions are generic type errors, they are not specific to any type