These are chat archives for dry-rb/chat

4th
Sep 2017
Alexander
@cutalion
Sep 04 2017 09:22
hey. I'm wondering if somebody here uses dry-transaction?
Tim Riley
@timriley
Sep 04 2017 09:24
Yes
Alexander
@cutalion
Sep 04 2017 09:32
It is not always convenient for me to pass single argument to "operation/transaction".
Does this approach give some benefits?
Alexander
@cutalion
Sep 04 2017 09:40
@timriley how do you provide context which is used in several steps? Or how do you omit this.
Probably the most common example in web apps would be providing "current_user" or other request context (locale, ip address)
I've tried to pass Hash as input. operation.call(user: current_user, params: params)
but then I had to add to my steps few lines for extracting user and params
user = input.fetch(:user)
params = input.fetch(:params)
Alexander
@cutalion
Sep 04 2017 09:54
maybe there is not other way to implement "railway oriented programming". Just wondering how people doing this.
Nikita Shilnikov
@flash-gordon
Sep 04 2017 10:19
@cutalion you can pass context using constructor
class MyTransaction
  include Dry::Transaction

  attr_reader :current_user

  def initialize(current_user:, **rest)
    super(rest)

    @current_user = current_user
  end

  step :has_user

  def has_user(greeting)
    Right(greeting % { name: current_user.name })
  end
end

result = MyTransaction.new(current_user: OpenStruct.new(name: 'John Doe')).("Hi, %{name}!")
Alexander
@cutalion
Sep 04 2017 10:21
It wouldn't be possible to use DI and dry-system's containers then, right?
(even without auto-registration)
Nikita Shilnikov
@flash-gordon
Sep 04 2017 10:25
nope. Actually, I discovered a way to do so but it's quite "dangerous" because you can inject current_user using DI anywhere
which is obvoiusly not a good idea in general
I'm testing this approach in my app and will release it as a separate gem or extension once I find all corner cases/rough edges
Tim Riley
@timriley
Sep 04 2017 10:32
@cutalion in terms of passing things like the current user, yes, your option is to create some kind of “context object” that you pass as your input to all your step operations
Which you’ve sort of half-done with your hash that you’ve been passing
In general, I try to pass things things in only when they are absolutely needed
so another idea would be to pass additional step arguments explicitly, like we demonstrate at the bottom of http://dry-rb.org/gems/dry-transaction/basic-usage/
if you didn’t want to do that every time you called your transaction, you could even wrap that up inside an overridden #call method on the transaction
I haven’t tried this myself, but something like:
def call(params, current_user:)
  with_step_args(some_step: [current_user: current_user]).call(params)
end
so this transaction may have several steps, but only some_step requires a “curent user” – that’s an idea of how you could pass it to one step without having to burden the other steps with it being part of their call signatures
Alexander
@cutalion
Sep 04 2017 10:35
thanks for idea! this looks nice.
Maybe I'll try it )
Tim Riley
@timriley
Sep 04 2017 10:35
np! hope it helps!
if you find whole groups of operations all needing extra things like current user (in my app, it is actually a whole bunch of operations that need “current basket” and “current order”), then I’d look into creating a first-class “context object” that properly encapsulates the passing around of that data
@flash-gordon We gotta be careful to avoid the dry-rb edition of the CurrentAttributes furore ;)
Nikita Shilnikov
@flash-gordon
Sep 04 2017 10:40
@timriley it doesn't have to be in dry-rb anyway and sould come with a huge disclaimer. Also, I can make it to allow inject say current_user to views only
Tim Riley
@timriley
Sep 04 2017 10:42
haha, yeah, I’m not actually worried :)
Alexander
@cutalion
Sep 04 2017 10:42
I think the problem with passing context to constructor is that object/transaction become not reusable.
It might ok in http api request, for instance, but not so good in background jobs
Tim Riley
@timriley
Sep 04 2017 10:42
we kinda built “globals” already for dry-view because that current_user case is so common there
@cutalion yeah, I reckon if you can get away with passing data to #call, it’d be preferable
Nikita Shilnikov
@flash-gordon
Sep 04 2017 10:43
In my case there is a context in 95% of the code, at the same time I don't tolerate global vars, what I use is effectively a closure, not a gvar
Tim Riley
@timriley
Sep 04 2017 10:44
yeah, that’s a real win if you’re otherwise having to pass it around everywhere
Nikita Shilnikov
@flash-gordon
Sep 04 2017 10:58
@timriley in fact, this a typical saas where all customers are completely isolated so that all queries include the tenant_id = condition, that's why I think it will be useful for other people
Tim Riley
@timriley
Sep 04 2017 10:59
@flash-gordon yeah, that’d be helpful
Alexander
@cutalion
Sep 04 2017 15:01
is it possible to auto-register dry-validation schemas with the auto_register feature of dry-system.
It tries to call .new on instance of schema
module Validation
  module Announcements
    Create = Dry::Validation.Form(Base) do
      # ...
    end
  end
end
Create - is an instance of class, no method new there
Alexander
@cutalion
Sep 04 2017 15:17
     NoMethodError:
       undefined method `new' for #<#<Class:0x00000007e7cf78>:0x00000007efd740>
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-system-0.5.1/lib/dry/system/loader.rb:48:in `call'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-system-0.5.1/lib/dry/system/component.rb:113:in `instance'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-system-0.5.1/lib/dry/system/auto_registrar.rb:35:in `block (3 levels) in call'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-container-0.6.0/lib/dry/container/item.rb:29:in `call'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-container-0.6.0/lib/dry/container/resolver.rb:25:in `call'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-container-0.6.0/lib/dry/container/mixin.rb:112:in `resolve'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-container-0.6.0/lib/dry/container/mixin.rb:125:in `[]'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-auto_inject-0.4.3/lib/dry/auto_inject/strategies/kwargs.rb:14:in `block (3 levels) in define_new'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-auto_inject-0.4.3/lib/dry/auto_inject/strategies/kwargs.rb:13:in `each'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-auto_inject-0.4.3/lib/dry/auto_inject/strategies/kwargs.rb:13:in `each_with_object'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-auto_inject-0.4.3/lib/dry/auto_inject/strategies/kwargs.rb:13:in `block (2 levels) in define_new'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-system-0.5.1/lib/dry/system/loader.rb:48:in `call'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-system-0.5.1/lib/dry/system/component.rb:113:in `instance'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-system-0.5.1/lib/dry/system/auto_registrar.rb:35:in `block (3 levels) in call'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-container-0.6.0/lib/dry/container/item.rb:29:in `call'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-container-0.6.0/lib/dry/container/resolver.rb:25:in `call'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-container-0.6.0/lib/dry/container/mixin.rb:112:in `resolve'
     # /home/cutalion/.rvm/gems/ruby-2.3.3/gems/dry-container-0.6.0/lib/dry/container/mixin.rb:125:in `[]'
Nikita Shilnikov
@flash-gordon
Sep 04 2017 15:19
@cutalion I just don't store schemas in a container
Alexander
@cutalion
Sep 04 2017 15:24
ah.. it's actually auto-import thing, notauto-register
or auto-register, but it just not called when I not import it )
Nikita Shilnikov
@flash-gordon
Sep 04 2017 15:27
it's because dry-system alsways initalize deps, this should be configurable but I don't know how
Alexander
@cutalion
Sep 04 2017 15:32
it doesn't seems to be. maybe with my own autoregistrar...
Alexander
@cutalion
Sep 04 2017 16:14
well, I'm moving forward ) How to use dry-monitor? Are there any examples?
Alexander
@cutalion
Sep 04 2017 16:27
:( it's not compatible with rom 4
well, I probably have to install if from some branch
Alexander
@cutalion
Sep 04 2017 16:32
for somebody's interest, need to update dry-configurable gem and then install dry-monitor