These are chat archives for dry-rb/chat

12th
May 2016
Fran Worley
@fran-worley
May 12 2016 04:21
@apotonick hey sorry it's been a while how's it going?
Nick Sutterer
@apotonick
May 12 2016 04:47
all good here, how are you @fran-worley ? where've you been?
Fran Worley
@fran-worley
May 12 2016 04:50
@apotonick I'm pretty good thanks. I've been really tied up with work part of which involved using dry-logic and dry-types to power something hence my being here! How goes the land of trailblazer?
Nick Sutterer
@apotonick
May 12 2016 05:17
trailblazer is going great! waiting to incorporate the new dry-v into reform! what's dry-logic?
BTW i'm shortly getting back to formular, i do hope you will still help out!!
@fran-worley is there a chance for "custom validations" in dry-v? we'd love to have arbitrary code being executed as a rule, or predicate, or whatever that would be. talked to @solnic a while ago, he said it's doable?
Fran Worley
@fran-worley
May 12 2016 05:24
dry-logic is used by both dry-v to do the logic bit take a rule and process it. I use it independently to process logic unrelated to validation. It's in dry-logic that you will find the base predicates.
I'm happy to help with formular but I parked it as our app uses erb and I just could resolve that little nightmare!
Fran Worley
@fran-worley
May 12 2016 05:32
@apotonick can you elaborate on what you mean by custom validations? You can already write your own predicates which can be then be used in validations.
Nick Sutterer
@apotonick
May 12 2016 05:38
yepp, but those have to be related to a specific input field. we need something like "check if max. 5 items", which has no input field
i played a lot with it, without success
Fran Worley
@fran-worley
May 12 2016 05:40
Ah see that's where reform comes in for me. If I need things like that I make them available to the form variable which you so helpfully injected into the schema. I can then do just that!
Nick Sutterer
@apotonick
May 12 2016 05:44
but, that didn't work for me, because i didn't find a way to instruct dry-v to "accept" that custom validation
Fran Worley
@fran-worley
May 12 2016 05:44
i know a lot is being done
Nick Sutterer
@apotonick
May 12 2016 05:44
same idea here, the actual code would sit in the form object, but i'd love dry-v to call it for me
Fran Worley
@fran-worley
May 12 2016 05:45
Strange any code you can post? I'm pre morning coffee so probably aren't ready you quite right...
Nick Sutterer
@apotonick
May 12 2016 05:45
how do you add that kind of validation in your code, @fran-worley ?
what, no coffee? i won't talk to you until you have one :coffee:
almost beer-o-clock here
Fran Worley
@fran-worley
May 12 2016 05:47
I create a custome predicate which calls my form.some_method. Then I can hook an error to my predicate and call the predic
Ergh the gitter app sucks sometimes!
Nick Sutterer
@apotonick
May 12 2016 05:48
ahaaa, and now it's your turn to give me some code. but go have your coffee first
because that's kinda the only thing why reform 2.2 is still waiting
Fran Worley
@fran-worley
May 12 2016 05:51
I'm sure that @solnic will come up with a much better way but I'll stick up a gist with some examples of how I use I get around it at the moment.
Nick Sutterer
@apotonick
May 12 2016 05:55
that would be amazing, @fran-worley. also, formular? you're up for another session in a week?
Fran Worley
@fran-worley
May 12 2016 05:57
I could possibly find some time on Friday. Spent a lot of yesterday on dry-v so need to catch up a little. I had a lot of ideas on where to go with it which would be useful to talk through. I wanted to make a big overhaul to the base code (from memory) even have the start of a PR.
Nick Sutterer
@apotonick
May 12 2016 05:59
you mean dry-v or formulario?
Fran Worley
@fran-worley
May 12 2016 06:09
Formular
Nick Sutterer
@apotonick
May 12 2016 06:11
:heart_eyes: i have some changes in mind, too. let's talk next week!
Fran Worley
@fran-worley
May 12 2016 06:32
This code is from dry-v 0.6.0 and could be improved alot but here are a couple of simple examples: https://gist.github.com/fran-worley/8da7d06f047c8ac512da9a195a37473f
Nick Sutterer
@apotonick
May 12 2016 06:48
thanks @fran-worley you're the best :rocket:
Fran Worley
@fran-worley
May 12 2016 06:48
@apotonick I may have completely misunderstood you of course!
Nick Sutterer
@apotonick
May 12 2016 07:08
yes and no, because you still have a specific field that you target with that validation
so, if wrong, the error message is gonna be against that field
whereas i would like to be able to add "random" error messages
Tim Riley
@timriley
May 12 2016 07:11
You can use high-level rules for that, I would say, nick
you can certainly name the rules however you like
Nick Sutterer
@apotonick
May 12 2016 07:16
i tried that, too, @timriley but something didn't work, i think the name got into my way
Fran Worley
@fran-worley
May 12 2016 07:16
@apotonick I get what you mean I'all have a play and let you know where I get too. High level rules are the way to go but I'm not sure whether they are tied to other rules as all the examples show them to be
Christopher Dennl-Ortega Arrieta
@cdennl
May 12 2016 07:28
@apotonick maybe it is possible to "hack" it like rails way
having a virtual property base
and do all random validations against base
which has no value which is evaluated
although that is not a clean solution
Benjamin Klotz
@tak1n
May 12 2016 10:06
@solnic, @timriley shit I merged my branch into master by accident :S
should I reset it and force push?
I forced pushed it to commit dry-rb/dry-validation@27c1224
sorry :S
Andy Holland
@AMHOL
May 12 2016 10:11
@tak1n accidents happen, don't worry about it
Fran Worley
@fran-worley
May 12 2016 10:12
@tak1n with your branch is there a way to have the arguments named intelligently rather than arg0 arg1 etc. ?
Benjamin Klotz
@tak1n
May 12 2016 10:13
@AMHOL okay :D
@fran-worley nope I only got the args itself not the name of it
I would also prefer to name them adequately
at best to the real param name of the custom_predicate
Fran Worley
@fran-worley
May 12 2016 10:13
@tak1n can you leave it open for a bit I would like to have a play if you don't mind ... ?
Benjamin Klotz
@tak1n
May 12 2016 10:14
@fran-worley yep will push it to a seperate branch in dry-v and reopen the pr
Andy Holland
@AMHOL
May 12 2016 10:14
Could use parameters to extract the names?
need to find the appropriate place
:)
Fran Worley
@fran-worley
May 12 2016 10:15
@AMHOL that is what I was thinking. If we can get the names then we might be able to clean up the options_for methods for built in predicates
Andy Holland
@AMHOL
May 12 2016 10:15
That would be cool :)
Benjamin Klotz
@tak1n
May 12 2016 10:15
I will push it to a branch and take a look on the parameters after lunch :)
cu later all
Andy Holland
@AMHOL
May 12 2016 10:17
Cya later
Tim Riley
@timriley
May 12 2016 10:23
@tak1n no worries about that push, thankfully git is flexible! Thanks for your work :)
Benjamin Klotz
@tak1n
May 12 2016 11:01

am I right with the assumption that for supporting the arg names we have to change the ast and also Dry::Logic::Predicate

https://github.com/dry-rb/dry-validation/blob/master/lib/dry/validation/result.rb#L58 the error_ast is generated out of of Validation::Error objects which hold the result which in turn holds the rule which in turn holds the predicate in it:

[6] pry(#<Dry::Validation::Result>)> errors.first
=> #<Dry::Validation::Error name=:text result=#<Dry::Logic::Result::Named success?=false input={:text=>"This is just dummy text"} rule=#<Dry::Logic::Rule::Key predicate=#<Dry::Logic::Predicate id=:custom_limit args=[5]> options={:evaluator=>#<Dry::Logic::Evaluator::Key path=[:text]>, :name=>:text}>>>
[7] pry(#<Dry::Validation::Result>)> errors.first.result
=> #<Dry::Logic::Result::Named success?=false input={:text=>"This is just dummy text"} rule=#<Dry::Logic::Rule::Key predicate=#<Dry::Logic::Predicate id=:custom_limit args=[5]> options={:evaluator=>#<Dry::Logic::Evaluator::Key path=[:text]>, :name=>:text}>>
[8] pry(#<Dry::Validation::Result>)> errors.first.result.rule
=> #<Dry::Logic::Rule::Key predicate=#<Dry::Logic::Predicate id=:custom_limit args=[5]> options={:evaluator=>#<Dry::Logic::Evaluator::Key path=[:text]>, :name=>:text}>
[9] pry(#<Dry::Validation::Result>)> errors.first.result.rule.predicate
=> #<Dry::Logic::Predicate id=:custom_limit args=[5]>
[10] pry(#<Dry::Validation::Result>)> errors.first.result.rule.predicate.args
=> [5]
so this has to change in Dry::Logic that predicates not only hold the args but also the information on what the name of the arg was?
Fran Worley
@fran-worley
May 12 2016 11:03
@tak1n I'm working on that bit of drylogic as we speak. could we make args a hash and the ast end up something like this?
[:input, [:compare, [
   :result, [1, [:check, [:compare, [:predicate, [:predicate_name?, [[:arg_one, 1], [:arg_two, 2], [:arg_three, 3]]]]]]]]
 ]
At present you get this
[:input, [:compare, [
   :result, [1, [:check, [:compare, [:predicate, [:eql?, [1]]]]]]]
 ]
Fran Worley
@fran-worley
May 12 2016 11:15
@tak1n at this point https://github.com/dry-rb/dry-logic/blob/master/lib/dry/logic/predicate.rb#L15
We can get the name of the predicate arguments by calling block.parameters
Benjamin Klotz
@tak1n
May 12 2016 11:18
I thought smth like that, thx :)
but the question is how should we transform this into the ast any suggestions on how this should like?
oops should have read the above mesasge too
haha :D
Fran Worley
@fran-worley
May 12 2016 11:19
@tak1n that is the dry-logic ast NOT the error ast.
Benjamin Klotz
@tak1n
May 12 2016 11:19
@fran-worley yes but the error ast depends on dry logic predicates and therefore the ast dry logic provides as far as I see
Fran Worley
@fran-worley
May 12 2016 11:20
Right ok I'll branch dry-v once I've worked out how to join the arg name with the value
Benjamin Klotz
@tak1n
May 12 2016 11:20
okay cool thx :)
just ping me and I can use ur branch from dry-logic to drive the development in dry-v for this :)
Tom Willis
@twillis
May 12 2016 12:38
@timriley @apotonick on the higher level rules. what i'm seeing is that the custom predicate can't get the values that are being validated at least in the gist I posted. https://gist.github.com/twillis/d7a4249ec77b5da5988a4a9d62a2a83d I would really love to see an example of that kind of thing working if it possible.
Piotr Solnica
@solnic
May 12 2016 12:50
@twillis should be rule(unique_email_address: [:email_address, :id]) { |id, email_address| id.unique_email_address?(email_address) }
@twillis the idea for the dsl is that the value on which you "call" a predicate becomes the first argument of the actual predicate, the dsl is virtual, but I can see how that confused you, we should make it work the way you tried it too
Tom Willis
@twillis
May 12 2016 12:57
hmmm ok yeah, the docs were a little light on this area so at a cursory glance it looked possible and obviously surprised me when it didnt. I'll try what you suggested. and report back.
Piotr Solnica
@solnic
May 12 2016 13:10
@twillis btw this key(:first_name).required { str? & max_size?(50) } should be key(:first_name).required(:str?, max_size?: 50)
required is a macro and currently we don't support blocks :(
Tom Willis
@twillis
May 12 2016 13:11
oh ok thanks for the guidance
Piotr Solnica
@solnic
May 12 2016 13:11
we're gonna add support for blocks in 0.8.0 with a ton of other improvements and bug fixes
@twillis btw if something is allowed to be nil do this: key(:middle_name).maybe(:str?, max_size?: 50)
and if you have duplication like in your example you can define a constrained type and use that, you can find an example in this post
Tom Willis
@twillis
May 12 2016 13:46

ok so i'm getting the values passed in now but the way @solnic example ends up having the parameters reversed. this works as expected however

  rule(unique_email_address: [:id, :email_address]) do |id, email_address|
    email_address.unique_email_address?(id)
  end

so i'm trying to understand this behavior so I can communicate it to the rest of my team.

Andy Holland
@AMHOL
May 12 2016 13:47
You enjoy your 11 days "off" @solnic ?
@twillis the arguments are reversed AFAIK
Tom Willis
@twillis
May 12 2016 13:51
is that intentional though?
Andy Holland
@AMHOL
May 12 2016 13:51
Not sure whether the actual arguments that get passed are reversed, or whether the subject is just appended to the arguments
Yeah it's intentional
Makes sense to me if the subject is appended, but not if the whole argument list is reversed
Tom Willis
@twillis
May 12 2016 13:52
how does the rule determine the subject? last arg? second arg?
Andy Holland
@AMHOL
May 12 2016 13:52
But as @solnic mentioned, it will be nicer when it works the way you initially expected
@twillis it doesn't matter, but generally I think the first argument to rule is used as the subject
Tom Willis
@twillis
May 12 2016 13:54
if i'm understanding you correctly, i would expect that :id would have been the subject then right?
Andy Holland
@AMHOL
May 12 2016 13:56
Yeah, that's right
Tom Willis
@twillis
May 12 2016 14:00
ok i'm more confused then, it seems like email_address needs to be the treated as subject in order for things to get passed in in the right order.
Piotr Solnica
@solnic
May 12 2016 14:07
@twillis age.gt?(10) translates to predicate being applied like that: age?(10, age_value)
Tom Willis
@twillis
May 12 2016 14:09
you mean gt?(10, age_value) ?
Piotr Solnica
@solnic
May 12 2016 14:09
ugh, right
sorry, I'm in two places right now
Tom Willis
@twillis
May 12 2016 14:09
ok i think i'm getting it I appreciate the guidance
Piotr Solnica
@solnic
May 12 2016 14:17
initial version of the dsl was key(:age) { |age| age.int? & age.gt?(10) } but that turned out to be too messy so we now evaluate blocks in the context of a value-rule builder, so you have key(:age) { int? & gt?(10) } but in the high-lvl rules we don't do that, hence confusion. We gotta improve this part of the lib for sure
Luca Guidi
@jodosha
May 12 2016 14:17
Folks, is it possible to customize an error message only for a key for a specific schema?
schema = Dry::Validation.Schema do
  required(:age).filled(:int?, gt?: 18)
end

result = schema.call(age: 11)
result.messages.fetch(:age)

# Actual
# => ["must be greater than 18"]

# Wanted
# => ["must be an adult"]
Andy Holland
@AMHOL
May 12 2016 14:20
@jodosha you can use a namespace
Wow
Gitter changed A LOT
I don't like it
Luca Guidi
@jodosha
May 12 2016 14:22
@AMHOL Thank you very much! :green_heart:
LOL :D
I still see the old UI
Andy Holland
@AMHOL
May 12 2016 14:22
Refresh
Luca Guidi
@jodosha
May 12 2016 14:23
Cmd+Shift+R (force refresh), but still old UI
Andy Holland
@AMHOL
May 12 2016 14:24
Maybe they're AB testing or something
Luca Guidi
@jodosha
May 12 2016 14:24
yup
Fran Worley
@fran-worley
May 12 2016 14:24
@jodosha same for me!
Andy Holland
@AMHOL
May 12 2016 14:25
Lucky you
Luca Guidi
@jodosha
May 12 2016 14:25
@fran-worley now I'm curious :D
Andy Holland
@AMHOL
May 12 2016 14:25
Found a bug already :laughing:
Piotr Solnica
@solnic
May 12 2016 14:26
Screen Shot 2016-05-12 at 16.26.30.png
it works great for me ^
Andy Holland
@AMHOL
May 12 2016 14:27
@solnic try clicking from something in all rooms to a room that you're in
Luca Guidi
@jodosha
May 12 2016 14:27
:joy:
Fran Worley
@fran-worley
May 12 2016 14:27
@jodosha no fair :crying_cat_face:
Andy Holland
@AMHOL
May 12 2016 14:27
So go from dry-web to chat for example
Ahh, they fixed it
It's gonna take some getting used to, but the UI is pretty cool
Piotr Solnica
@solnic
May 12 2016 14:29
it's not, it's very buggy, I had it enabled for a week and went back to the old one
but now they are releasing it to everybody, I hope they will fix the bugs
Fran Worley
@fran-worley
May 12 2016 14:35
@solnic in dry-logic is it reasonable to assume that the last argument of a predicate will always be the input (unless there are no args)
Andy Holland
@AMHOL
May 12 2016 14:36
Still got no idea how to join a new room
Fran Worley
@fran-worley
May 12 2016 14:36
@AMHOL I only ever seem to do it by mistake when on the app and then its impossible to leave..
Andy Holland
@AMHOL
May 12 2016 14:37
Yeah lol that's really annoying
William Howard
@whoward
May 12 2016 14:40
hey guys - is it possible to define a custom Dry Type Coercible? can't seem to find much in the docs about it
Piotr Solnica
@solnic
May 12 2016 14:51
@fran-worley it is
@whoward wdym by coercible?
Fran Worley
@fran-worley
May 12 2016 14:55
@solnic and last is safer than searching for an argument called input
William Howard
@whoward
May 12 2016 14:56
i'm meaning like if i wanted to write a custom type like Type::UUIDArray
sorry its kind of a weak case, i'm trying to hack in a fix for my database adapter
Type::PGArray - i know this is better handled in a mapper but I don't really know how to write those yet :)
Piotr Solnica
@solnic
May 12 2016 15:00
@whoward YourType = Dry::Types::Definition.new(SomePrimitiveClass).constructor { |value| ... }
Luca Guidi
@jodosha
May 12 2016 15:01
@solnic I was going to ask a similar question: what about POROs? See dry-rb/dry-validation#161 for a reference
Piotr Solnica
@solnic
May 12 2016 15:02
POROs?
William Howard
@whoward
May 12 2016 15:02
Plain old ruby objects :)
Luca Guidi
@jodosha
May 12 2016 15:02
(yes I hate that term, but it's common use)

Let's say I have this class:

require 'uri'

class Url
  def initialize(arg)
    @url = URI.parse(arg)
    freeze
  end
end

How to use it for validations?

@kwando suggested to register the type: Dry::Types.register_class(Url). Now I can do: required(:website) { type?(Url) }
Now the problem arises when I receive unexpected input: that causes URI.parse to blow up. That means I have to surround form.call invocation with a begin/rescue block.
Luca Guidi
@jodosha
May 12 2016 15:07
@solnic Is there any chance to use a less strict policy for this? Does Dry::Types::Definition.new(SomePrimitiveClass).constructor { |value| ... } solves this problem? Thanks :)
Piotr Solnica
@solnic
May 12 2016 15:13
your type should handle unexpected input
why do you need custom types like that for validation?
Luca Guidi
@jodosha
May 12 2016 15:15
@solnic to reuse existing logic.

your type should handle unexpected input

If I do that, how can type?(Url) fail?

Piotr Solnica
@solnic
May 12 2016 15:20
it should rescue and return original value, that's the contract, we either manage to coerce or we don't
btw, your Url should receive a parsed url value instead of doing that in the constructor
Luca Guidi
@jodosha
May 12 2016 15:23
So I can't register class with default #initialize, because Ruby doesn't allow to return a type different from self.class.
So I should do:
class Url
  def self.fabricate(arg)
    new URI.parse(arg)
  rescue URI::InvalidURIError
    arg
  end
end

Dry::Types.register_class(Url, :fabricate)
Piotr Solnica
@solnic
May 12 2016 15:26
yep
fwiw I think coercing in constructors is a smell :)
Luca Guidi
@jodosha
May 12 2016 15:27
That could happen in for third party code.
Piotr Solnica
@solnic
May 12 2016 15:28
you can always wrap things with a dry-type like in your example, so that won't be a problem

you can always wrap things with a dry-type like in your example, so that won't be a problem

Do you mean this: Dry::Types::Definition.new(SomePrimitiveClass).constructor { |value| ... } ?

Piotr Solnica
@solnic
May 12 2016 15:33
yes
you can 1) set the primitive class 2) provide coercion logic including error handling
Hannes Nevalainen
@kwando
May 12 2016 15:52
raising a TypeError in your coercion method will make a schema fail a validation instead of blowing up
Piotr Solnica
@solnic
May 12 2016 15:53
we don't want to blow up schema
validation is a process of trying to see if the data is valid
Luca Guidi
@jodosha
May 12 2016 15:54
yes, that's the point ;)
@kwando @solnic This works as expected:
class Url
  def initialize(arg)
    @url = URI.parse(arg)
  rescue URI::InvalidURIError
    raise TypeError
  end
end

Dry::Types.register_class(Url)

schema = Dry::Validation.Form do
  required(:website).filled(type?: Url)
end

result = schema.call(website: ['']) # This doesn't blow up, but gracefully fails
Piotr Solnica
@solnic
May 12 2016 15:59
good to know :D
Luca Guidi
@jodosha
May 12 2016 15:59
@kwando Thank you again! :)
Hannes Nevalainen
@kwando
May 12 2016 16:02
I do not really like the fact that raising an Exception is the only way to tell dry-v a type is invalid
Luca Guidi
@jodosha
May 12 2016 16:03
Yes :+1:
Piotr Solnica
@solnic
May 12 2016 16:04
it is not
the only way
in fact, I'd be against doing it like that
just return original value and it won't match against primitive type
don't do it in initializer/new, do it in dry-type's constructor
Hannes Nevalainen
@kwando
May 12 2016 16:05
@solnic didn't know that, thx for the hint! <3
Piotr Solnica
@solnic
May 12 2016 16:06
Url = Dry::Types::Definition.new(URI).constructor { |v| begin; URI.parse; rescue URI::InvalidURIError => e; v; end }
this should work but there's a risk because of dry-rb/dry-types#87 it won't work :/
Tom Willis
@twillis
May 12 2016 16:07

ok next question regarding arrays/nested ... I have this portion of the schema...

  key(:organization_users).required do
    each do
      schema do
        key(:id).maybe(:str?)
        key(:org_uid).required(:str?)
        key(:roles).required(min_size?: 1).each(:str?)
      end
    end
  end

and it does not fail when roles is nil

{:organization_users=>[{:id=>"222", :roles=>nil, :org_uid=>"333"}]}

I may be interpreting something in the docs

Piotr Solnica
@solnic
May 12 2016 16:08
@twillis not supported yet :( it's a known limitation, there's an issue reported, we'll fix/improve in 0.8.0
you can workaround that with a high-level rule
Tom Willis
@twillis
May 12 2016 16:09
ok I'll go read the issue
thanks
Piotr Solnica
@solnic
May 12 2016 16:10
rule(min_roles: [:roles]) { |roles| roles.min_size?(1) }
each implies array? check too, so you're safe
Fran Worley
@fran-worley
May 12 2016 16:12
Piotr Solnica
@solnic
May 12 2016 16:13
@fran-worley I honestly don't remember, remove .reverse and see which specs are failing
Fran Worley
@fran-worley
May 12 2016 16:14
@solnic thanks don't think I need it any more. I assume that any changes to the ast is considered a breaking change?
Piotr Solnica
@solnic
May 12 2016 16:15
@fran-worley depends, if you change the structure of existing node types then yes, it's gonna break things
Fran Worley
@fran-worley
May 12 2016 16:15

I want this:
[:input, [:compare, [:result, [1, [:check, [:compare, [:predicate, [:eql?, [2]]]]]]]]]

to become:
[:input, [:compare, [:result, [1, [:check, [:compare, [:predicate, [:eql?, [[:left, 1], [:right, 2]]]]]]]]]

So essentially the arg names and values are included in the ast not just the values. I think this should enable us to really clean up the error message handling in dry-v and make the ast more readable
Phil Schalm
@pnomolos
May 12 2016 16:16
@AMHOL I figured out the issue (re railtie) - Dry::Types.type_map holds a reference to the type as well
Andy Holland
@AMHOL
May 12 2016 16:17
Oh, nice one :)
So it's working now?
Fran Worley
@fran-worley
May 12 2016 16:17
and when I say I want I mean I've nearly finished writing it... just got to sort out each and check...
Luca Guidi
@jodosha
May 12 2016 16:22

Folks, I've got another question about error messages:

        configure do
          config.namespace     = :user
          config.messages_file = 'test/fixtures/messages.yml'
        end

        required(:age).filled(:int?, gt?: 18)
en:
  errors:
    rules:
      user:
        rules:
          age:
            gt?: "must be an adult"

This works, but it looks complex to reproduce. Is there any chance to simplify like this?

en:
  errors:
    user:
      age:
        gt?: "must be an adult"
Piotr Solnica
@solnic
May 12 2016 16:23
I...think so?
Phil Schalm
@pnomolos
May 12 2016 16:24
@AMHOL I have a proof of concept working, but definitely need to clean it up. My spec is passing, though :D
Andy Holland
@AMHOL
May 12 2016 16:25
@pnomolos nice, thanks for figuring this out
Piotr Solnica
@solnic
May 12 2016 16:26
@fran-worley hmmmmm I think you're right :)
Phil Schalm
@pnomolos
May 12 2016 16:26
@AMHOL After hours of beating my head against the wall it was a definite “D’oh” moment when I realized that it was being held by the type_map as well >.<
Piotr Solnica
@solnic
May 12 2016 16:26
error/hint compiling is still waiting for a big refactor, removing nested key syntax is done but I haven't had time to clean/simplify things yet
Luca Guidi
@jodosha
May 12 2016 16:27
@solnic Cause for a single failure it tries to lookup ~30 keys.
Fran Worley
@fran-worley
May 12 2016 16:29
@solnic once I've got these specs to pass I'll take a look at dry-v I think it should mean we will only need one options_for that will work with base and custom predicates using the correct arg names
Piotr Solnica
@solnic
May 12 2016 16:30
@jodosha we cache message templates so that shouldn't be a problem
Luca Guidi
@jodosha
May 12 2016 16:30
@solnic Ok :D
Piotr Solnica
@solnic
May 12 2016 16:30
@fran-worley this would be great, really
Fran Worley
@fran-worley
May 12 2016 16:31
@solnic just got to get check not to recreate the predicate....
Christopher Dennl-Ortega Arrieta
@cdennl
May 12 2016 16:39
@twillis the argument list is indeed reversed
@twillis you can verify this by declaring a predicate with >= 3 arguments
Tom Willis
@twillis
May 12 2016 16:39
as I understand it intentionally
Christopher Dennl-Ortega Arrieta
@cdennl
May 12 2016 16:39
yes
it is
I got trapped by this as well
v1.my_predicate?(v2, v3,v4) == def my_predicate?(v4,v3,v2,v1) end;
Fran Worley
@fran-worley
May 12 2016 16:41
Christopher Dennl-Ortega Arrieta
@cdennl
May 12 2016 16:43
@fran-worley yes, maybe I didn't dig into it
should be documented at some time :)
Tom Willis
@twillis
May 12 2016 17:32
ok i'm having trouble getting this working. and it's probably due to my misunderstanding of the docs in regards to an array of nested attributes. here's a gist. https://gist.github.com/twillis/99b34cf02d56c05baa34e9f672672a0f
Piotr Solnica
@solnic
May 12 2016 17:37
@twillis required does not support blocks
Tom Willis
@twillis
May 12 2016 17:37
arghhhhh
ok
Piotr Solnica
@solnic
May 12 2016 17:37
Just do key(:data).each ...
Tom Willis
@twillis
May 12 2016 17:50
thanks much @solnic hope i'm not being too annoying I swear I read the docs. :P I think i'm getting the hang of it now
Fran Worley
@fran-worley
May 12 2016 17:51
@twillis I wouldn't worry about it. I know the docs are a little out of date so it's always worth double checking on here before wasting too much time!
Piotr Solnica
@solnic
May 12 2016 18:33
@twillis no worries. Feedback and questions are welcome
Nikita Shilnikov
@flash-gordon
May 12 2016 18:51
jruby-9.1.0.0 :001 > [1, [1, []]].hash
 => 0
jruby-9.1.0.0 :002 > [2, [2, []]].hash
 => 0
weird
Tom Willis
@twillis
May 12 2016 19:21

ok working on error messages now, the last step!!! hopefully.

UserPayloadValidator = Dry::Validation.Schema do
  configure do
    config.messages_file = NavigatorApi::App.settings.errors_file
    config.namespace = :user_payload
    def unique_email_address?(id, email_address)
      ApplicationContext.with_user 'DEVADMIN' do
        existing_user = AppUser
                          .association_join(person: :person_email_address)
                          .where('person_email_address.email_address = ?',
                                 email_address)
                          .first
        # the existing email address might belong to the user we're trying to
        # update
        if existing_user.present? && id && existing_user.user_uid != id
          false
        else
          true
        end
      end
    end
  end

  key(:id).maybe(:str?, size?: 36)
  key(:email_address).maybe(:str?,
                            format?: /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i,
                            max_size?: 255)
  rule(unique_email_address: [:id, :email_address]) do |id, email_address|
    email_address.unique_email_address?(id)
  end
end
en:
  errors:
    rules:
      user_payload:
        rules:
          first_name:
            filled?: "First Name is required"
          last_name:
            filled?: "Last Name is required"
          unique_email_address?: "%{email_address} is not unique"

getting an error about it missing. i'm not grokking the docs apparently...


  1) UserPayload#valid? email_address for an existing app_user when an existing email exists has errors
     Failure/Error: expect(payload.errors[:email_address]).to be_present
     Dry::Validation::MissingMessageError:
       message for unique_email_address? was not found
     # ./app/lib/payloads/application_payload.rb:12:in `valid?'
     # ./app/lib/payloads/application_payload.rb:21:in `errors'
     # ./spec/app/lib/payloads/user_payload_spec.rb:152:in `block (5 levels) in <top (required)>'
Ralf Schmitz Bongiolo
@mrbongiolo
May 12 2016 20:58
@twillis did you tried so:
en:
  errors:
    rules:
      user_payload:
        rules:
          first_name:
            filled?: "First Name is required"
          last_name:
            filled?: "Last Name is required"
          email_address:
            unique_email_address?: "%{email_address} is not unique"
Tom Willis
@twillis
May 12 2016 21:02
oh cool that worked. I think
it's blowing up on %{email_address} now but I'm going to move on. thanks so much
Phil Schalm
@pnomolos
May 12 2016 21:26
@AMHOL Thanks for the help on this: jeromegn/dry-types-rails#3
Andy Holland
@AMHOL
May 12 2016 21:32
Nice work @pnomolos :)
Phil Schalm
@pnomolos
May 12 2016 21:34
@AMHOL Thanks, only had to check the calling stack in one place to deal with the autoloader 😭
Andy Holland
@AMHOL
May 12 2016 21:34
lol yeah I noticed that
Phil Schalm
@pnomolos
May 12 2016 21:35
Unless someone with more experience dealing with Rails’ autoloader can give me another way to detect if a constant is autoloaded while it’s being autoloaded, I think that’s the only way to deal with it
Joe Van Dyk
@joevandyk
May 12 2016 22:26
@pnomolos will that work for things like dry-container?
Phil Schalm
@pnomolos
May 12 2016 22:35
@joevandyk Doubtful - the gem specifically hooks into the dry-types registration system. What sort of issues are you having with dry-container?
Joe Van Dyk
@joevandyk
May 12 2016 22:35
none yet, just figured there would be :)
Phil Schalm
@pnomolos
May 12 2016 22:37
One issue I can think of with dry-container is re-registering an item. Unfortunately I think the only way around that to deal with Rails would be to write your own registry for any container you’re using that doesn’t throw an error if a registration key already exists.
Joe Van Dyk
@joevandyk
May 12 2016 22:38
@pnomolos should there be a dry-container-rails and so on?
Phil Schalm
@pnomolos
May 12 2016 22:39
With dry-types-rails it’s worked around by explicitly deleting the keys from the container, but that only works if you are able to monitor the whole “stack”. If you’re using a container in a reloadable environment the only other solution I see is making sure the entire container is reloaded.
I’m actually not using dry-container explicitly yet (baby steps ;)) so I’m not sure, quite possibly if there becomes a need. As I said, though, the solution is rather hamfisted in nature
Joe Van Dyk
@joevandyk
May 12 2016 23:28
@pnomolos yes, i’m having problems adding a new thing to the registry with dry-container — reloading won’t see it.
(Didn’t need it for dry-types-rails, but you may find it handy :))
Joe Van Dyk
@joevandyk
May 12 2016 23:32
actually if I follow rails conventions, like put AutoInject = Dry::AutoInject(MyContainer) into app/models/auto_inject.rb, it works fine afaic
and put MyContainer in app/models/my_container.rb
i can update stuff and it seems to work
Phil Schalm
@pnomolos
May 12 2016 23:33
As long as the whole container is reloaded you’re fine (Because it’s starting from scratch every time)
Joe Van Dyk
@joevandyk
May 12 2016 23:43
if using dry auto inject and want to unit test it, do i need to always use positional arguments?
i.e if I have include AutoInject[“dep1”, “dep2”] and I want to change dep2 for a test (make it a spy/double or something), do I have to pass in dep1 as well? like SomeClass.new(dep1, dep2)?