Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • 17:31
    jswanner commented #141
  • 06:15
    lazebny starred dry-rb/dry-types
  • Feb 19 22:35
    solnic commented #141
  • Feb 19 22:32

    solnic on v0.17.0

    (compare)

  • Feb 19 22:32

    solnic on master

    Bump dry-system to 0.17.0 (compare)

  • Feb 19 22:31

    solnic on 141-fix-compat-with-dry-configurable

    Bump dry-system to 0.17.0 (compare)

  • Feb 19 22:31

    dry-bot on master

    [devtools] update changelog.yml… [devtools] sync (compare)

  • Feb 19 22:27

    solnic on 141-fix-compat-with-dry-configurable

    (compare)

  • Feb 19 22:27

    solnic on master

    Fix compatibility with dry-conf… Merge pull request #142 from dr… (compare)

  • Feb 19 22:27
    solnic closed #142
  • Feb 19 22:27
    solnic closed #141
  • Feb 19 22:24
    solnic milestoned #141
  • Feb 19 22:23
    solnic opened #142
  • Feb 19 22:23

    solnic on 141-fix-compat-with-dry-configurable

    Fix compatibility with dry-conf… (compare)

  • Feb 19 21:12
    flash-gordon commented #141
  • Feb 19 20:45
    jswanner opened #141
  • Feb 19 20:45
    jswanner labeled #141
  • Feb 19 17:38
    pmackay starred dry-rb/dry-monads
  • Feb 19 17:18
    tomraithel starred dry-rb/dry-types
  • Feb 19 11:51
    yingce starred dry-rb/dry-types
Jaromír Červenka
@Cervajz
I use it like this:
class ApplicationSchema < Dry::Validation::Schema
  configure do |config|
    option :record
    option :machine_repository, Machine
    option :user_repository, User
    option :temporary_token_repository, TemporaryToken

    config.messages_file = 'config/locales/validations.yml'
  end

...

end

module Sessions
  AuthenticateUserSchema = Dry::Validation.Schema(ApplicationSchema) do
    required(:email).filled(:str?)
    required(:password).filled(:str?)

    validate(exists?: :email) do |email|
      user_repository.find_by(email: email).present?
    end
  end
end
Kacper Pucek
@KacperPucek
[1] pry(main)> Dry::Validation.Schema
=> #<#<Class:0x00007fb7c16fe4a8>:0x00007fb7c794ba70
 @checks={},
 @config=
  #<#<Class:0x00007fb7c0d8e760>:0x00007fb7c16fe2c8
   @config=
    {:input_processor=>:noop,
     :hash_type=>:weak,
     :type_map=>{},
     :path=>[],
     :predicates=>Dry::Logic::Predicates,
     :registry=>#<Dry::Validation::PredicateRegistry::Unbound:0x00007fb7c16fe0e8 @external=Dry::Logic::Predicates, @predicates={}>,
     :messages=>:yaml,
     :messages_file=>#<Pathname:/Users/xxxx/xxxx/xxxx/config/locales/validations.yml>,

vs

[2] pry(main)> Dry::Validation.Params
=> #<#<Class:0x00007fb7c0d2d4d8>:0x00007fb7c0cdbae8
 @checks={},
 @config=
  #<#<Class:0x00007fb7c1b09f48>:0x00007fb7c0d2c3a8
   @config=
    {:input_processor=>:params,
     :hash_type=>:symbolized,
     :type_map=>{},
     :path=>[],
     :predicates=>Dry::Logic::Predicates,
     :registry=>#<Dry::Validation::PredicateRegistry::Unbound:0x00007fb7c0d27448 @external=Dry::Logic::Predicates, @predicates={}>,
     :messages=>:yaml,
     :messages_file=>nil,

Only in case of Dry::Validation.Schema messages_file is present

@Cervajz
I can get it to work this way or another, that's not an issue. I'm just wondering if this is expected behaviour or maybe I'm just doing something conceptually wrong here :D
Jaromír Červenka
@Cervajz
@KacperPucek The parent for your Params (Schema) class is different :)
If you want to share configuration, you need to reuse the Schema while calling .Params method
As:
def self.Params(base = nil, **options, &block)
      klass = base ? Schema::Params.configure(Class.new(base)) : Schema::Params
      Validation.Schema(klass, options, &block)
end
In your example:
config=
  #<#<Class:0x00007fb7c0d8e760>:0x00007fb7c16fe2c8
   @config=

vs

@config=
  #<#<Class:0x00007fb7c1b09f48>:0x00007fb7c0d2c3a8
   @config=
    {:input_processor=>:params,
two different objects
(as per their ID)
Or I can be completely wrong :D
Jaromír Červenka
@Cervajz
So what I'd do is Dry::Validation.Params(MyParentSchemaWithConfig) do ... end
Kacper Pucek
@KacperPucek
Thanks for looking into this, that's exactly what I ended up with for now - simply Dry::Validation.Params(Dry::Validation::Schema). Thanks again :)
Jaromír Červenka
@Cervajz
We would probably have to look how dry-configurable works.
Interesting
Now I am trying to understand how that works :D
Jaromír Červenka
@Cervajz
From line #19
And it's parent is Schema
So it's acutally Schema.configure do |config| on that line #9
I am lost :/
Pablo Crivella
@pablocrivella
What would be the best/easiest to mock the result of a Dry::Transcation::Operation when it returns a block?
Operation.new.call(arg) do |result|
  result.success { ... }
  result.failure { ... }
end
Piotr Solnica
@solnic
@pablocrivella are you using rspec?
Pablo Crivella
@pablocrivella
Yes
Piotr Solnica
@solnic
too bad your operation is not injected and you manually instantiate it
this makes mocking it harder
Pablo Crivella
@pablocrivella
I will try the injected version ASAP then :)

Is it still possible to inject a operation, even if i’m using inside other operation:

i.e:

class CheckAccess
  include Dry::Transaction::Operation

  def call(user)
    return Success(user.licenses.first) if active_license_for?(user)

    check_purchase = CheckPurchase.new
    check_purchase.call(user.purchases.first) do |result|
      result.success do |purchase|
        Success(purchase)
      end

      result.failure do
        if user.on_trial?
          Success(Trial.new(user: user))
        else
          Failure(user)
        end
      end
    end
  end

  private

  def active_license_for?(user)
    user.licenses.first_or_initialize.active?
  end
end
Viet (Drake) Tran
@tiev
I prefer not using that block syntax at all. It’s a kind of dry-matcher Class enhancement.
I think it’s just a sugar-syntax that’s hard to write tests.
Just use normal Result matcher.
Or better, with the nature of your code, use Do notation
Tim Riley
@timriley
In that context I personally would just use the plain Result API
check_purchase.call(user.purchases.first).or {
  if user.on_trial?
    Success(Trial.new(user: user))
  else
    Failure(user)
  end
}
Tim Riley
@timriley
@pablocrivella also, that check_purchase operation cannot injected given you hard code its initialization in the call method
if you want it to be an injected dependency, you need to pass it to initialize
e.g.
def initialize(check_purchase:)
  @check_purchase = check_purchase
end
Then you can use it from inside #call and also inject a test double during your tests
Pablo Crivella
@pablocrivella
Thanks @timriley ! I’ll take a look
Pablo Crivella
@pablocrivella
There is not something similar to include Dry::Transaction(container: Container) for Operations right? Is that a flaw on my desing? should operations not depend on other operations as a common practice?
Tim Riley
@timriley
@pablocrivella you want dry-auto_inject for that
Pablo Crivella
@pablocrivella
@timriley Yeah i checked that one but i’m having a hard time wrapping my head around how it should be the correct way of including it on a rails project.
For now i went for the “hybrid” approach:
# frozen_string_literal: true

require "dry/transaction/operation"

class CheckAccess
  include Dry::Transaction::Operation

  def initialize(check_purchase: CheckPurchase.new)
    @check_purchase = check_purchase
  end

  def call(user)
    return Success(user.licenses.first) if active_license_for?(user)

    @check_purchase.call(user.purchases.first).or(
      if user.on_trial?
        Success(Trial.new(user: user))
      else
        Failure(user)
      end
    )
  end

  private

  def active_license_for?(user)
    user.licenses.first_or_initialize.active?
  end
end
David Dawson
@DangerDawson
@pablocrivella I take a similar approach, plus you can always use the following gem: https://github.com/dry-rb/dry-initializer for your initializer
Matheus Silva Santos de Oliveira
@matheussilvasantos
Does someone know how to validate an optional field with a set of values?
I found this in documentation required(:sample).value(eql?: 1234), but I the field I want to validate is optional and there is more than one value that it could be.
Piotr Solnica
@solnic
@matheussilvasantos required(:sample).maybe(included_in?: [1, 2, 3])
Matheus Silva Santos de Oliveira
@matheussilvasantos
@solnic thank you!!
Igor Alexandrov
@igor-alexandrov
@matheussilvasantos if you have optional key (it may be missed in input) then you should use optional instead of required
optional(:sample).maybe(included_in?: [1, 2, 3])
Igor Alexandrov
@igor-alexandrov
irb(main):013:0> VALUE = 1
=> 1
irb(main):014:0> Dry::Monads::Success(Dry::Monads::Success(VALUE))
=> Success(Success(1))
I always thought that it should be just Success(1)