These are chat archives for dry-rb/chat

14th
Oct 2016
Nick Sutterer
@apotonick
Oct 14 2016 06:04
hey @timriley i have a question about dry-auto_inject (again), because i decided we're not using dry-initializer (we don't need coercion, types, etc. at this point), but we simply have two arguments initialize(params, options) where options are all the dependencies injected
now i have two things
  1. how would i extend Ai to "eat" the two-arg version params, options? (i think you hinted this twice already)
  2. can we change Ai to not add any readers but only merge the auto-injected parameters into the options hash? that would all happen on the class-level
Nick Sutterer
@apotonick
Oct 14 2016 06:16
@timriley i see that i might have to write my own strategy. fine with that, but you gotta help me!!! :tea:
Yurii Danyliak
@yuriidanyliak
Oct 14 2016 09:06
Hey guys! Just a quick question: is there some ability to use dry-validation output with form_for or deliver the results of validation to front-end in some elegant way?
Nick Sutterer
@apotonick
Oct 14 2016 09:06
@yuriidanyliak yes, with reform!
Yurii Danyliak
@yuriidanyliak
Oct 14 2016 09:07
Hello @apotonick ! Yes, already read about reform-rails. Is there any way to use schema output with reform?
Nick Sutterer
@apotonick
Oct 14 2016 09:08
schema "output", what is that?
you can use reform with dry-validation, it's pretty amazing
Yurii Danyliak
@yuriidanyliak
Oct 14 2016 09:08
Sorry, going to clarify.
Nick Sutterer
@apotonick
Oct 14 2016 09:08
;)
UserSchema.call({}).output :)

you can use reform with dry-validation, it's pretty amazing

Great, OK then!

Will try, thanks Nick! BTW: you had great presentation at #pivorak!
Nick Sutterer
@apotonick
Oct 14 2016 09:11
oh thanks :blush: it was a fantastic audience, really!
Yurii Danyliak
@yuriidanyliak
Oct 14 2016 09:12
:blush: have a nice weekend
Nick Sutterer
@apotonick
Oct 14 2016 09:12
go try reform, i can help you with everything, but @fran-worley is our pro
Yurii Danyliak
@yuriidanyliak
Oct 14 2016 09:12
Ok )
Tim Riley
@timriley
Oct 14 2016 09:13
@apotonick if I don't have a new baby at start of the work, I'll see if I can take a quick stab at a strategy for you
Nick Sutterer
@apotonick
Oct 14 2016 09:14
@timriley :heart_eyes: so, i would basically not implement define_initializer, right?
my initializer looks like
def initialize(params, options)
  @options = options #this is the dependency hash
end
so i kinda want to avoid the overriding from Ai
because we don't need separate instance variables per dependency, i store them all in one hash
@yuriidanyliak what does Schema#output do?
Yurii Danyliak
@yuriidanyliak
Oct 14 2016 09:17
output's result of validation, those data that passed the validation of schema
@apotonick, usually using like
validation = schema.call(params)
validation.success? ? validation.output : validation.messages
Tim Riley
@timriley
Oct 14 2016 09:25
Yeah, looks like you could skip defining the initializer, @apotonick
Nick Sutterer
@apotonick
Oct 14 2016 11:21
@timriley i'll play with it now and let ya know
@yuriidanyliak ok, but what's the meaning of "output" in this specific case?
Fran Worley
@fran-worley
Oct 14 2016 11:25
@apotonick output gives you pack your params
Nick Sutterer
@apotonick
Oct 14 2016 11:26
i see
so basically form.sync
Fran Worley
@fran-worley
Oct 14 2016 11:34
Not its used after validation and just literally returns params. More like form.to_nested_hash
Nick Sutterer
@apotonick
Oct 14 2016 11:48
here we go
Fran Worley
@fran-worley
Oct 14 2016 11:59
:) it's a dry-validation method that we don't use in reform.
Piotr Solnica
@solnic
Oct 14 2016 13:52
Please use Result#to_h instead of output
Ivo Benedito
@ivobenedito
Oct 14 2016 15:49
hey guys!
starting to try to replace my Virtus addiction by dry-types 😜
I have a domain object that maps a remote API resource object ... and for example some of the attributes are DateTime instances
& for example, the responsability of coercion for DateTime values should be done outside of the object itself?
Ivo Benedito
@ivobenedito
Oct 14 2016 15:54
just asking, because if I run something like: class User < Dry::Struct; attribute :created_at, Types::DateTime; end; User.new(created_at: "2016-10-06T10:03:03.785Z")
it won't coerce anything and will just put a string on the object state
Piotr Solnica
@solnic
Oct 14 2016 15:56
@ivobenedito use dry-validation schema to process data before passing it to your structs
Ivo Benedito
@ivobenedito
Oct 14 2016 15:59
@solnic I'm really interested in shifting to dry-rb, but I'm finding it to be a little hard to read and find docs / blog posts about how to connect all this sub-modules together
Piotr Solnica
@solnic
Oct 14 2016 16:04
@ivobenedito just apply schema validation to api input, and pass result to struct constructor, there’s no need to “connect” anything
User.new(schema.call(some_data_from_api)) <= just this
of course validation can fail so you may want to handle this however you want
Ivo Benedito
@ivobenedito
Oct 14 2016 16:06
yeah I've understood that, it's a great tip thx
but that forces the schema to be defined twice somehow, right?
on the struct, and on the schema definition
and the schema definition contains validation logic, also
and how will a DateTime coercion/parsing will be done on a Schema object :/
Piotr Solnica
@solnic
Oct 14 2016 16:32
@ivobenedito use Dry::Validation.JSON and add type expections, like date_time? etc. it will infer coercions from that and try to apply them
I’d do something like this:
UserSchema = Dry::Validation.JSON do
  required(:created_at).value(:date_time?)
end

class User < Dry::Struct
  attribute :created_at, Types::Strict::DateTime
end

user_attrs = UserSchema.(user_data)

User.new(user_attrs)
in 1.0.0 dry-validation will support infering schemas from struct definitions, for now you need to have it defined explicitly in both places
Ivo Benedito
@ivobenedito
Oct 14 2016 16:35
and that JSON validation enforces the coercion? cool
Screen Shot 2016-10-14 at 17.33.33.png
this is the service object where I'm trying to inject that Schema logic you're talking about
so that you understand the context a little better
Piotr Solnica
@solnic
Oct 14 2016 16:44
@ivobenedito aah so the structure is different (camel-cases keys)
anyhow, yes it will enforce coercions
Ivo Benedito
@ivobenedito
Oct 14 2016 16:44
yah ... camel-cased but I don't want to make the case switch automatically
Piotr Solnica
@solnic
Oct 14 2016 16:44
why do you have a guard for an empty string? is it an allowed value?
Ivo Benedito
@ivobenedito
Oct 14 2016 16:45
the external API is returning unexpected values in some cases
let's say ... users that never logged in, the last_sign_in_at datetime doesn't exist
don't even know if I just tell the API owners to returning an empty field or just skip the field on the response
Piotr Solnica
@solnic
Oct 14 2016 16:47
yeah this is exactly why I recommend using schemas instead of just blindly passing input to domain structs
so, uhm, you can do all sorts of things to make it easier to work with potentially garbage-data
unfortunately JSON schemas don’t turn empty strings to nils
(Form schemas do)
I’ve been thinking about changing that, it’s not gonna be pedantically correct, but it’d be very pragmatic
if you need more control over input and coercions, you can turn on explicit type specs, and define custom types where you need them
it’s gonna be more verbose but you’d get full control
Piotr Solnica
@solnic
Oct 14 2016 16:54
ie:
DateOrNil = Types::Strict::Date.optional.constructor { |v|
  v ==  '' ? nil : Types::Json::Date[v]
}

schema = Dry::Validation.JSON do
  configure { config.type_specs = true }

  required(:date, DateOrNil).maybe(:date?)
end

irb(main):038:0> schema.(date:  '')
=> #<Dry::Validation::Result output={:date=>nil} errors={}>
irb(main):039:0> schema.(date: '2010-10-12')
=> #<Dry::Validation::Result output={:date=>#<Date: 2010-10-12 ((2455482j,0s,0n),+0s,2299161j)>} errors={}>
Ivo Benedito
@ivobenedito
Oct 14 2016 17:55
hmmm yes!
Ivo Benedito
@ivobenedito
Oct 14 2016 18:36
what's the config.type_specs for?
Yurii Danyliak
@yuriidanyliak
Oct 14 2016 18:49
to specify type for coercion explicitly, as far as I know
Piotr Solnica
@solnic
Oct 14 2016 22:51
Yes. What Yurii said. It'll be default behaviour in 1.0.0
Nick Sutterer
@apotonick
Oct 14 2016 23:13
@solnic i will be at RubyDay, too, that means we can hack! (or drink)
Piotr Solnica
@solnic
Oct 14 2016 23:46
@apotonick w00000t
(We shall do both)
Nick Sutterer
@apotonick
Oct 14 2016 23:55
i do agree!