These are chat archives for dry-rb/chat

19th
Feb 2016
Andrew Kozin
@nepalez
Feb 19 2016 11:58

@solnic, @AMHOL Hi!

@marshall-lee and me have recently written dry-initializer gem with a simple DSL for fast definition:

require 'dry-initializer'

class User
  extend Dry::Initializer

  parameter :name, default: 'Unknown',      type: String # dry-types will be supported as well
  option    :type, default: -> { 'admin' }, type: String
end

user = User.new 'Joe', type: 'customer'

which is the same as:

class User
  attr_reader :name, :type

  def initialize(name = 'Unknown', type: 'admin')
    @name = name
    @type = type
    # ... type constraints follows here
  end
end

Could you please create a dry-initializer repo for the gem and give us corresponding rights?
I'd prefer to push it on place from the very beginning.

Andy Holland
@AMHOL
Feb 19 2016 12:07
Hi @nepalez, that's great, I'll set that up now
Done
Andrew Kozin
@nepalez
Feb 19 2016 12:10
...and what about access rights? ;)
@AMHOL ^^
Andy Holland
@AMHOL
Feb 19 2016 12:10
I've invited you to the core-contributors group
Which has write access
Andrew Kozin
@nepalez
Feb 19 2016 12:11
thank you
Andy Holland
@AMHOL
Feb 19 2016 12:12
NP
Piotr Solnica
@solnic
Feb 19 2016 12:13
dry-constructor vs dry-initializer might be confusing
Andrew Kozin
@nepalez
Feb 19 2016 12:16
@AMHOL could you add @marshall-lee as a committer too?
*contributor
Andy Holland
@AMHOL
Feb 19 2016 12:16
He's already in core-contributors
@solnic should it be called something else?
Vladimir Kochnev
@marshall-lee
Feb 19 2016 12:22
yo
we decided not to propose a patch to dry-constructor because the scope of changes is big
Andrew Kozin
@nepalez
Feb 19 2016 12:23
@solnic @AMHOL @marshall-lee let you guys decide about the name. I'll be back in the evening
Andy Holland
@AMHOL
Feb 19 2016 12:23
Cool, cya later
Vladimir Kochnev
@marshall-lee
Feb 19 2016 12:40
@solnic @AMHOL dry-initializer was extracted from my work in https://github.com/marshall-lee/function_object which should be rewritten to use dry-initialize. may I import it as a dry-function ?
to dryrb
Michał Pietrus
@blelump
Feb 19 2016 13:16

Hi guys!

Having such piece of code:

require 'i18n'
require 'dry-validation'

class UserSchema < Dry::Validation::Schema
  configure { config.messages = :i18n }

  key(:email) {|email| email.filled? > email.password_valid? }

  def password_valid?(email)
    false
  end
end

schema = UserSchema.new
p schema.call(email: '', password: 19).messages
 # {}

it returns valid, whereas as I understand the docs, it should at least tell me that the email must be filled. Is it correct behaviour?

Alexander Chernik
@achernik
Feb 19 2016 13:28

@blelump as far as I can tell, you need to change > to &:

key(:email) {|email| email.filled? & email.password_valid? }

>, I beleive, is for high-level rules (which depend on values of different keys)

rule(:email_absence) do
  value(:login).false? > rule(:email).none?
end
Michał Pietrus
@blelump
Feb 19 2016 13:30
@achernik , thanks for your response :-) . Well, generally I'd like to have a rules chain, e.g. when rule X is valid, then it goes to check rule Y etc
Oskar Szrajer
@gotar
Feb 19 2016 13:30
it's by default works like that I think. It's break checking when find first error
Michał Pietrus
@blelump
Feb 19 2016 13:42

uhm, perhaps such piece of code would explain what I'm trying to achieve:

  key(:email) {|email| email.filled?  }
  key(:password, &:filled?)

  rule(:user_active) do
    value(:email).account_active?
  end

  rule(:valid_password) do
    value(:email).password_valid?
  end

Basically the idea is to perform a few checks, where each check depends on the previous one. I might follow the @achernik way and put it in such way: email.filled? & email.password_valid? & email.account_active?, however in such case the validation result always concerns the :email field which I fell is not the expected behaviour.

Perhaps you guys have a better approach for that?

Fran Worley
@fran-worley
Feb 19 2016 14:04
@blelump I actually do the same thing you need using Dry-V. Your first piece of code is actually saying if email is filled, then validate password. It is not actually requiring Email to be filled. What you could do is check that email is filled, then validate the password only if email is filled.
Alexander Chernik
@achernik
Feb 19 2016 14:07
I'm lost now :worried: really can't grasp the difference between value(:email).none? and rule(:email).none?
Fran Worley
@fran-worley
Feb 19 2016 14:38
@solnic wrote a message on this. But essentially, value(:key) calls up a predefined key and applies methods to it. so if you had key(:email. &:filled?) you could access that with value(:email).none?
Piotr Solnica
@solnic
Feb 19 2016 14:39
rule(:foo).bar? will be gone in next version
the diff right now is that rule(:foo).bar? checks if bar? predicate was successfuly applied, w/o applying it again
so it operates on existing results
which I removed
so, it’s gone, you’ll always use value syntax
@achernik ^
@blelump can you describe exactly what you’re trying to do?
Piotr Solnica
@solnic
Feb 19 2016 14:44
it should be possible already, I believe, but rule syntax is tricky so you might have issues with getting it right
Alexander Chernik
@achernik
Feb 19 2016 14:47

i guess this ?

# pseudocode, no idea if this is right
rule(:credentials_match) do
  value(:email).filled? & value(:email).email? & value(:password).filled? & value(:password).valid_password?(value(:email))
end

btw, is this the right way? :)

Michał Pietrus
@blelump
Feb 19 2016 15:30
@fran-worley , yep, you have right, but only if things would be that easy... :-) . In this case I'd need extra validation logic, e.g if user is active checker. Anyway thanks!
Fran Worley
@fran-worley
Feb 19 2016 15:33
@blelump in my case we have some users who's accounts are restricted (they can't log on) emails and passwords are not required for users with restricted accounts.
It's a couple more lines than the active model if: syntax but clearer and with the improvements in the dry-v API the lines of code are shrinking all the time :) :heart: @solnic
Michał Pietrus
@blelump
Feb 19 2016 15:36
@solnic , what I'm trying to achieve is somewhat a rules chain. Imagine a case when key(:email, &:filled?) and key(:password, &:filled?) are valid. Then (but only if these params are filled) I'd like to perform another validation logic, with some checking , e.g.
– if user and password are filled, check whether user is active
– if user and password are filled and user is active, check whether user can log in
Piotr Solnica
@solnic
Feb 19 2016 15:51
rule(password: :valid) do
  (rule(:email).email? & rule(:password).filled?) > value(:password).valid?
end
@blelump try this ^
this will look for a msg under errors.password.valid
Michał Pietrus
@blelump
Feb 19 2016 15:53
@solnic , thanks :-) , however what if I'd like to check first if user is active ?
Piotr Solnica
@solnic
Feb 19 2016 15:53
(value(:email).active? > value(:password).valid?)
> is an alias to then
so it’s rule(:email).email?.and(rule(:password).filled?)).then(…)
Michał Pietrus
@blelump
Feb 19 2016 16:04

@solnic ,

  key(:password) {|pass| pass.filled?}
  key(:email) {|email| email.filled?}

  rule(:user_active) do
    (rule(:email).filled? & rule(:password).filled?) > value(:email).user_active?
  end

  def user_active?(email)
    false
  end

gives:

dry-logic-0.1.2/lib/dry/logic/rule/result.rb:5:in `[]': no implicit conversion of Symbol into Integer (TypeError)
Andy Holland
@AMHOL
Feb 19 2016 16:05
@marshall-lee https://github.com/dryrb/dry-function sorry I took so long :p
Michał Pietrus
@blelump
Feb 19 2016 16:17

@solnic , I've tried various chains, e.g:

  rule(:user_active) do
    rule(:email).filled?.and(rule(:password).filled?).then(rule(:email).user_active?).then(rule(:email).user_valid?)
  end

or

  rule(:user_active) do
    rule(:email).filled?.and(rule(:password).filled?).then(rule(:email).user_active?)
  end

  rule(:user_valid) do
    rule(:user_active).then(rule(:email).user_valid?)
  end

but it doesnt work. I'm lost now

Piotr Solnica
@solnic
Feb 19 2016 16:18
well, looks like a bug
Michał Pietrus
@blelump
Feb 19 2016 16:18
is it at least correct syntax ?
Piotr Solnica
@solnic
Feb 19 2016 16:18
I’m rewritting most of it so I’ll make sure it’s fixed in next release
I hoped to get it done by the end of the month but I got sick last Monday and spent the whole week in bed, so there will be a delay
and yeah it’s correct, but in 0.7.0 rule will only be used to define a high-level rule
inside the blocks you’ll just use value
and it’s gonna be completely flexible
wrt accessing values (including nested structures)
Michał Pietrus
@blelump
Feb 19 2016 16:21
uhm, well, many ppl got sick here in Cracow last days. hopefully all is fine now !
Piotr Solnica
@solnic
Feb 19 2016 16:21
I’m still sick actually :(
just got back to Kraków from Ząb, I’m sure our fresh air will help me get better :joy:
Michał Pietrus
@blelump
Feb 19 2016 16:22
yeah...
Piotr Solnica
@solnic
Feb 19 2016 16:22
and cześć Michał :)
Michał Pietrus
@blelump
Feb 19 2016 16:22
dzień dobry :-)
Piotr Solnica
@solnic
Feb 19 2016 16:24
anyways, I rewrote dry-logic, so now I gotta finish refactoring dry-v to make it work again, I’m super close to finish
Michał Pietrus
@blelump
Feb 19 2016 16:26

OK , great !

I'll try then to not complicate my validations until next release is out

Piotr Solnica
@solnic
Feb 19 2016 16:30
yeah, sorry about that. I’ll try to finish the new release asap
Michał Pietrus
@blelump
Feb 19 2016 16:34
sure :-) . @solnic , one more thing, is it possible to access another validated values from within custom validation method? Say I have def password_valid?(email); end – can I access password as well somehow ?
Piotr Solnica
@solnic
Feb 19 2016 16:35
in 0.6.0 you can do rule(:foo, password_valid?: [:email, :password])
then email and pass will be passed into this predicate
I hope :joy:
Michał Pietrus
@blelump
Feb 19 2016 16:39
well, it indeed is correct, but the rule is never fired
however when I remove password_valid?: [:email, :password], it fires
ah crap, I 've passed a block to it, sorry for interupting