Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
Jaromír Červenka
@Cervajz
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)
Igor Alexandrov
@igor-alexandrov
Don't know maybe #flatten or #compact should be added for such cases
Nikita Shilnikov
@flash-gordon
you usually use fmap/bind depending on the case, there's no flatten/join because it's normally not required
flattening by default will ruin the semantics
it won't "type check"
Igor Alexandrov
@igor-alexandrov
Ok, got it
Thanks!
Igor Alexandrov
@igor-alexandrov
The question above was because we tried to combine Try and Result monads, but we found a solution:
irb(main):003:0> Try { Failure(5) }.to_result.bind(&:itself)
=> Failure(5)
irb(main):004:0> Try { raise RuntimeError.new }.to_result.bind(&:itself)
=> Failure(#<RuntimeError: RuntimeError>)
irb(main):005:0> Try { Success(1) }.to_result.bind(&:itself)
=> Success(1)
Matheus Silva Santos de Oliveira
@matheussilvasantos
@igor-alexandrov yes, I'm using optional :smile:
hasimisikli
@hasimisikli
@solnic hello ,firstly thanks of uploaded. can I ask a question?
can you explain this project please?
Igor Alexandrov
@igor-alexandrov
@hasimisikli you mean to explain dry-rb?
hasimisikli
@hasimisikli
Yes.
Grant Shangreaux
@gcentauri
"dry-rb is a collection of next-generation Ruby libraries, each intended to encapsulate a common task"
@hasimisikli that might get you started
Herwin
@herwinw
Does dry-validation have something like input input.strict of dry-struct? I can't find any indication of it in the documentation
Igor S. Morozov
@Morozzzko
What are you trying to achieve?
Herwin
@herwinw
Working with a legacy app where a lot of logic is based on a nested hash. I'm convinced some keys have become obsolete and some keys contain typos, so I'm trying to work backwards to a schema where every entry of the hash adheres to, that gives a starting point to see what keys exactly exist. So I want the validation to error if extra keys are given.
I could also use dry-struct for it, but I'm not interested in the resulting struct (yet), and dry-validation gives more readable errors
Matheus Silva Santos de Oliveira
@matheussilvasantos
Is there a way to get only valid attributes from to_h method of Dry::Validation::Result?