These are chat archives for dry-rb/chat

30th
Nov 2015
Hannes Nevalainen
@kwando
Nov 30 2015 08:50
@solnic I'm struggling a bit on how to do something similar to this with dry-data and dry-validation. https://gist.github.com/kwando/9663d5781e34ee82a8f8
Hannes Nevalainen
@kwando
Nov 30 2015 09:23
Same thing but with dry components --> https://gist.github.com/kwando/01ff386521d46a432ebe
Piotr Solnica
@solnic
Nov 30 2015 09:29
@kwando @timriley input-type compiler is not finished, please gimme a day or two...
Hannes Nevalainen
@kwando
Nov 30 2015 09:30
Oh, I'm not complaining! Just feeding you one of my use cases =)
take your time, really
Piotr Solnica
@solnic
Nov 30 2015 09:46
I know, I’m just saying why it’s not working in some use cases yet :)
I’m working on it intesively
I realized yesterday I want to support arbitrary structures already in the compiler, which requires some changes in dry-data ast and adjustements in compiler on validation side
Tim Riley
@timriley
Nov 30 2015 10:28
@solnic no probs! thanks for letting us know :smile:
Piotr Solnica
@solnic
Nov 30 2015 11:49
@timriley @kwando stuff should work now
Tim Riley
@timriley
Nov 30 2015 11:56
@solnic you’re unstoppable
:muscle:
Piotr Solnica
@solnic
Nov 30 2015 11:59
:joy:
Tim Riley
@timriley
Nov 30 2015 11:59
So I actually have put this in our app now.
Piotr Solnica
@solnic
Nov 30 2015 11:59
this kind of stuff works, including coercion inference from type-predicates
Tim Riley
@timriley
Nov 30 2015 11:59
Nice – coercion inference is neat!
Piotr Solnica
@solnic
Nov 30 2015 11:59
what makes me really happy is that I can explicitly say that something can be none? | int?
and when an empty string is passed it will be coerced to nil…since that’s what we want in form params
Tim Riley
@timriley
Nov 30 2015 12:00
Right now I’ve made “form input” Dry::Data::Struct subclasses that use “form.*” coercions where it seems right (e.g. “form.bool”), and then I pass those to the validation schema. Does that seem reasonable?
Piotr Solnica
@solnic
Nov 30 2015 12:01
not really, structs are strict, they will raise when keys are missing
Tim Riley
@timriley
Nov 30 2015 12:01
Yeah, I had to work around that :grimacing:
Piotr Solnica
@solnic
Nov 30 2015 12:01
Schema::Form will do coercion for you
Tim Riley
@timriley
Nov 30 2015 12:01
So the idea is that the validation will coerce things?
Piotr Solnica
@solnic
Nov 30 2015 12:01
you just reminded me I need to add support for bool? :)
Tim Riley
@timriley
Nov 30 2015 12:01
haha
Yeah, the absence of bool was what made me wonder, haha!
Piotr Solnica
@solnic
Nov 30 2015 12:01
yes, we want coercion for forms
Tim Riley
@timriley
Nov 30 2015 12:01
“maybe there’s a superset of form stuff that I need to use dry-data directly for…"
Ok cool, this is great then! We can just use the validation schema.
Piotr Solnica
@solnic
Nov 30 2015 12:02
that’s why we have Schema::Form
Tim Riley
@timriley
Nov 30 2015 12:02
Right right, makes sense :)
I have to sleep now but I will rip out these form input structs in the morning, heh.
Piotr Solnica
@solnic
Nov 30 2015 12:02
I wasn’t sure if I want to keep coercion completely external until now
@timriley I’ll release dry-validation 0.2.0
Tim Riley
@timriley
Nov 30 2015 12:03
It’s feeling nice enough to you in the schema, then?
Piotr Solnica
@solnic
Nov 30 2015 12:03
just need to add that bool? predicate
Tim Riley
@timriley
Nov 30 2015 12:03
Fantastic!
I’m looking forward to demoing this stuff at rails camp in a couple of weeks. Just need to get all the concepts together in a cohesive talk!
Piotr Solnica
@solnic
Nov 30 2015 12:03
@timriley the schema defines rules, some of those rules are related to type-safety, for type-safety we need coercions, so…it makes perfect sense
Tim Riley
@timriley
Nov 30 2015 12:03
Yep.
Piotr Solnica
@solnic
Nov 30 2015 12:03
the trick here, however, is that we have separation
so plain schema won’t coerce
form schema will
and we can easily come up with other schema sub-types for other use-cases
like I dunno, json input validation
Tim Riley
@timriley
Nov 30 2015 12:04
Yeah, it’s good to keep them separate.
Piotr Solnica
@solnic
Nov 30 2015 12:04
with dry-data types it’s gonna be very flexible wrt coercion
@timriley you’re gonna have a lot to demo :joy:
Tim Riley
@timriley
Nov 30 2015 12:05
I’ll book a 2-hour slot ;)
Piotr Solnica
@solnic
Nov 30 2015 12:06
is it a talk or more like a workshop?
Tim Riley
@timriley
Nov 30 2015 12:06
It’ll be very informal. I’d encourage questions at any point and will deviate where necessary to respond to them :)
Was hoping to have a rough structure ready some point next week to get your thoughts on, if you don’t mind.
Piotr Solnica
@solnic
Nov 30 2015 12:16
@timriley yeah sure!
:joy:
46 x faster than AM/Virtus
Hannes Nevalainen
@kwando
Nov 30 2015 13:03
@solnic I don't think optional work correctly in form schemas =/
class PagingValidator < Dry::Validation::Schema::Form
  optional(:per_page) { |pp| pp.int? & pp.gt?(0) & pp.lteq?(100) }
  optional(:page) { |p| p.int? & p.gt?(0) }
end
result = PagingValidator.new.messages({'per_page' => '10'})
#<Dry::Validation::Schema::Result params={:per_page=>nil} errors=[[:per_page, ["per_page must be an integer"]]]>
If I use key instead of optional it coerces the same input to an int before validating
Hannes Nevalainen
@kwando
Nov 30 2015 13:12
btw, nice to see dry-validation be so fast! I actually thought it would be slower =P
Piotr Solnica
@solnic
Nov 30 2015 13:39
@kwando it was pointed out to me that I18n slows AM down
so we’ll see how fast it is when we integrate with I18n
but I’m quite positive it will be way faster than AM, even with I18n plugged in
@kwando please report an issue about that coercion problem with optionals
Hannes Nevalainen
@kwando
Nov 30 2015 13:43
@solnic issue created, do you prefer issues to be created right away or should I continue to run them by that first?
I would use dry-validation even if it was slower, have a great feeling this is the missing piece in my stack
Piotr Solnica
@solnic
Nov 30 2015 13:47
@kwando I can’t repro the issue in the spec, weird
@kwando ah ok got it, happens with more than one &s
Hannes Nevalainen
@kwando
Nov 30 2015 13:50
@solnic goodie =)
Piotr Solnica
@solnic
Nov 30 2015 13:53
ok, I see what’s going on, but I won’t have time to fix today
Hannes Nevalainen
@kwando
Nov 30 2015 13:54
no worries =)
Piotr Solnica
@solnic
Nov 30 2015 13:56
I was kidding
I just fixed it :joy:
Andy Holland
@AMHOL
Nov 30 2015 13:56
:joy:
Hannes Nevalainen
@kwando
Nov 30 2015 13:56
:thumbsup:
Andy Holland
@AMHOL
Nov 30 2015 13:56
I would use dry-validation even if it was slower, have a great feeling this is the missing piece in my stack @kwando me and @solnic were just saying the same thing lol
Hannes Nevalainen
@kwando
Nov 30 2015 13:57
nice, then I'm not the only crazy one around here
Andy Holland
@AMHOL
Nov 30 2015 13:57
:p definitely not
Piotr Solnica
@solnic
Nov 30 2015 13:58
@kwando the fix is pushed
but not released
I’ll wait for more bug reports from you :joy:
btw @AMHOL do you have any experience with i18n gem?
I’ve no idea what’s needed to implement an integration with it
Andy Holland
@AMHOL
Nov 30 2015 13:59
Very little TBH
Piotr Solnica
@solnic
Nov 30 2015 14:00
too bad it’s so slow though
Andy Holland
@AMHOL
Nov 30 2015 14:00
Yeah, I don't particularly like it
Some mixing of concerns in there, had to dig through the code just to figure out how to load translations from a hash
Maybe we should make dry-i18n :laughing:
Piotr Solnica
@solnic
Nov 30 2015 14:05
we should make dry-{everything} but it’s gonna take a lot of time :)
Andy Holland
@AMHOL
Nov 30 2015 14:05
Yep
Piotr Solnica
@solnic
Nov 30 2015 14:06
my friend and ex-co-worked used to/is a core contributor to i18n
so I may just ask him for help
Sven is also super cool and helpful and we kind-of know each other too
Andy Holland
@AMHOL
Nov 30 2015 14:06
Cool, is i18n integration going to be a separate gem?
Piotr Solnica
@solnic
Nov 30 2015 14:06
I’m on the fence with this tbh
Andy Holland
@AMHOL
Nov 30 2015 14:07
I know it's an extremely common use-case
But in an API for example, you wouldn't want i18n
Piotr Solnica
@solnic
Nov 30 2015 14:07
if I18n usage will be the most common one and we can do the integration with very little LOC
then it should probably be in dry-validation itself
if I get it right, we need to compile errors into a list of translation lookup paths
in correct order of course
Andy Holland
@AMHOL
Nov 30 2015 14:08
Yep
Piotr Solnica
@solnic
Nov 30 2015 14:08
and then just loop through those and ask I18n.t to get the message
Andy Holland
@AMHOL
Nov 30 2015 14:08
Probably also need a root key
Piotr Solnica
@solnic
Nov 30 2015 14:08
we have namespace setting in schemas
would that be root?
Andy Holland
@AMHOL
Nov 30 2015 14:08
It's pretty close you what you already have isn't it?
Yep it would
Piotr Solnica
@solnic
Nov 30 2015 14:09
oh and we also need to merge built-in messages into I18n translations
under en
Andy Holland
@AMHOL
Nov 30 2015 14:09
Yep
Piotr Solnica
@solnic
Nov 30 2015 14:10
this does feel like a small addition tbh
Andy Holland
@AMHOL
Nov 30 2015 14:10
My thinking with making it external, was that this feels like a bit of a smell to me
I was thinking that call would just return the errors, and you could DI a compiler to return what you need
It has the Ast compiler, which is just identity to return the Ast, then Hash to return hash messages for Api
Piotr Solnica
@solnic
Nov 30 2015 14:12
right, we could remove messages and just delegate to whatever compiler was injected to ask for final result
Andy Holland
@AMHOL
Nov 30 2015 14:13
Yep, so we can have I18n compiler
Piotr Solnica
@solnic
Nov 30 2015 14:13
totally
wait, who needs DI, let’s monkey-patch Array instead
Andy Holland
@AMHOL
Nov 30 2015 14:13
:joy:
[].messages is useful right?
Piotr Solnica
@solnic
Nov 30 2015 14:14
[].to_beautiful_error_messages
Andy Holland
@AMHOL
Nov 30 2015 14:14
lmao
Piotr Solnica
@solnic
Nov 30 2015 14:14
such expressive, very beautiful, wow :)
Andy Holland
@AMHOL
Nov 30 2015 14:15
much speed
Piotr Solnica
@solnic
Nov 30 2015 14:15
anyhow, currently error compiler has the concept of an injected messages object and it just calls lookup on it and passes data
so, error compiler makes the decision what data to extract from a particular error node
Andy Holland
@AMHOL
Nov 30 2015 14:15
Yeah, I noticed that
Piotr Solnica
@solnic
Nov 30 2015 14:15
and passes it to lookup
I wonder if we could simply have Messages::I18n
and inject it to the error compiler
it would have #lookup and receive stuff like :gt?, [18], 17
Andy Holland
@AMHOL
Nov 30 2015 14:17
Not sure about that myself, it makes the assumption that you want to translate/transform the messages in some way
I guess that would work for all cases, just return a hash for APIs an stuff?
Piotr Solnica
@solnic
Nov 30 2015 14:19
the purpose of messages is to get a string representation of an error
furthermore, you may want to have custom messages for cases where you need more data to produce a message and this data is not present in the errors
I guess we could dump errors into some generic representation that can be digested by external systems
although the error ast is already that representation
it has absolutely everything, including nested structures, for each violation you have the original input present, name of the predicate, its optional args etc
Andy Holland
@AMHOL
Nov 30 2015 14:27
Yeah, I get that, I just mean that you might not want a string representation of the errors in some cases
Piotr Solnica
@solnic
Nov 30 2015 14:28
@AMHOL well, we have Error objects already
that’s what call returns
result with error objects
Andy Holland
@AMHOL
Nov 30 2015 14:29
Yeah, I think it would be nice if you could use DI and have call return what you need in the context of your use-case
#messages seems like a specialisation, which introduces an un-necessary, context-specific API IMO
I.e. I could inject/configure Dry::Validation::Compilers::Hash.new or Dry::Validation::Compilers::I18n.new and have #call just return what I need
Piotr Solnica
@solnic
Nov 30 2015 14:31
yes that’s cool
Andy Holland
@AMHOL
Nov 30 2015 14:35
:+1:
Piotr Solnica
@solnic
Nov 30 2015 14:36
gotta run, ttyl
Andy Holland
@AMHOL
Nov 30 2015 14:38
:wave:
Benjamin Klotz
@tak1n
Nov 30 2015 15:33
"wait, who needs DI, let’s monkey-patch Array instead" , finally a comment which I can take out of context and post on twitter that solnic supports active support, but then again everyone who knows him knows that he doesn't :joy: :joy:
Piotr Solnica
@solnic
Nov 30 2015 15:34
@tak1n lol :)
Hannes Nevalainen
@kwando
Nov 30 2015 15:42
@solnic how about "dynamic" values in validation? Like "time" needs to be in the future
key(:time}{ |t| t.time? & t.gt?(Time.now) } won't work, maybe something like key(:time){ |t| t.time? & t.gt?{ Time.now }}
Hannes Nevalainen
@kwando
Nov 30 2015 15:48
Hmm, I can just use my own predicate ^^
Piotr Solnica
@solnic
Nov 30 2015 15:49
yes either a custom one or maybe we could add future? predicate
Hannes Nevalainen
@kwando
Nov 30 2015 15:50
yeah, there is probably some more useful predicates for working with date/time
Piotr Solnica
@solnic
Nov 30 2015 15:50
definitely
t.year?(2000) etc
Hannes Nevalainen
@kwando
Nov 30 2015 15:51
t.weekday? (though that one is locale specific)
How would the schema work when two keys is dependent on each other? a.int? & b.int? & a > b
Piotr Solnica
@solnic
Nov 30 2015 15:55
not implemented, yet
you’ll have something like this, soon:
Hannes Nevalainen
@kwando
Nov 30 2015 15:55
thought so =P
Piotr Solnica
@solnic
Nov 30 2015 15:56
on(:a, :b) { |a, b| a.gt?(b) }
this means “when :a and :b are valid, also check this"
not entirely sure how the dsl will look though
Hannes Nevalainen
@kwando
Nov 30 2015 15:57
ah ok, that would be very useful =)
Piotr Solnica
@solnic
Nov 30 2015 15:57
I know, it’s high on my list
it’s one of the many personal pet peeves I’ve got with AM::V that I want to fix in dry-v
Hannes Nevalainen
@kwando
Nov 30 2015 15:59
already love this => MyFormValidator.new.messages(params).params
Piotr Solnica
@solnic
Nov 30 2015 15:59
hah yeah, coerced params are sweet
and safe, ootb
I’ll add structure validation too, soon
Hannes Nevalainen
@kwando
Nov 30 2015 16:01
When you can use your own types and coercions this will be event sweeter =)
when/if
Piotr Solnica
@solnic
Nov 30 2015 16:01
you can
no public API for that yet though, but it’s possible
it’s only a matter of registering your type within dry-data and defining your predicate
…and extending type compiler, but we can collapse those 3 steps into a single method call
and extending type compiler means adding your_predicate => your_type mapping :joy:
sounded so serious when I wrote it :D
Hannes Nevalainen
@kwando
Nov 30 2015 16:06
oh? you're spoiling us <3
Piotr Solnica
@solnic
Nov 30 2015 16:07
dry-data is extendible, so is dry-validation
Hannes Nevalainen
@kwando
Nov 30 2015 16:08
I don't really like the globalness of Dry::Data right now
Piotr Solnica
@solnic
Nov 30 2015 16:09
yeah, I will probably add a way of setting your own container
I also thought about having a way to define types under constants, so it feels more natural to define things like attribute :foo, MyTypes::Something::Foo
but I dunno, we’ll see
Hannes Nevalainen
@kwando
Nov 30 2015 16:11
cool =)
feels like you have a plan for everything =P
Piotr Solnica
@solnic
Nov 30 2015 16:13
I certainly don’t, but I’ve thought about a ton things, I gotta say :)