These are chat archives for dry-rb/chat

5th
Apr 2016
Luca Guidi
@jodosha
Apr 05 2016 08:41 UTC
Good morning folks, I've got a question about dry-v. How to access coerced values? If I define:
key(:foo) { type?(String) }
And I call the validator with result = schema.call(foo: 1), result.output still has 1 as fixnum, instead of a "1", as string.
Is this a feature of Form, rather than of Schema? Am I missing something?
Thanks in advance :)
Benjamin Klotz
@tak1n
Apr 05 2016 08:44 UTC
@jodosha morning, as far as I know this should result in an error because u passed in a Integer where u said u are expecting a String, or I'm missing smth (just started to learn dry-v :P)
Luca Guidi
@jodosha
Apr 05 2016 08:45 UTC
@tak1n yup, it does. but I'm interested in coerced values. Is my expectation wrong?
you should use form schema for that I think
Prior validation, we need to coerce values and symbolize keys based on the information from rules
I only use Schema for now, did not have a look at Form yet
Luca Guidi
@jodosha
Apr 05 2016 08:49 UTC
@tak1n Thanks. I've probably got what's the behavior here. That works with Form, because of the sentence you quoted.
Benjamin Klotz
@tak1n
Apr 05 2016 08:49 UTC
as far as I understood it it's doing coercion with Dry::Types and u even can specify custom types to do custom coercion, @solnic correct me if I'm wrong there :)
@jodosha glad I could somehow help :D
Piotr Solnica
@solnic
Apr 05 2016 08:50 UTC
gimme a sec
Luca Guidi
@jodosha
Apr 05 2016 08:50 UTC
@tak1n Coercion works with non-string types, because forms always receive strings as inputs.

Example 1:

irb(main):001:0> form = Dry::Validation.Form do
irb(main):002:1* key(:foo) { type?(String) }
irb(main):003:1> end

irb(main):004:0> form.call(foo: 1)
=> #<Dry::Validation::Result output={:foo=>1} messages={:foo=>["must be String"]}>
# foo is still an integer, expected string

Example 2:

irb(main):001:0> form = Dry::Validation.Form do
irb(main):002:1* key(:foo) { type?(Integer) }
irb(main):003:1> end

irb(main):004:0> form.call(foo: '1')
=> #<Dry::Validation::Result output={:foo=>1} messages={}>
# foo is now coerced from string to integer
Piotr Solnica
@solnic
Apr 05 2016 08:54 UTC
yes, Schema by default has no input processor attached
Schema.Form infers coercions from type expectations
Luca Guidi
@jodosha
Apr 05 2016 08:55 UTC
@solnic Gotcha, thank you! Is it intentional that it doesn't attempt to coerce String types? See Example 1.
Piotr Solnica
@solnic
Apr 05 2016 08:56 UTC
yes, because it’s designed to work with data coming from a form submission, so it’s strings, arrays and hashes, exclusively
Luca Guidi
@jodosha
Apr 05 2016 08:56 UTC
@solnic Perfect, thank you very much! :+1:
@tak1n Thank you for the Form reference :+1:
Benjamin Klotz
@tak1n
Apr 05 2016 08:57 UTC
@jodosha np :clap:
Benjamin Klotz
@tak1n
Apr 05 2016 09:04 UTC

@solnic I got another problem
Basically I want to trigger rules depending on the platform but for now the platform was a string and doing platform.eql?('twitter') worked fine
but what I really want to have is a platforms array where I trigger rules depending on which platforms u try to publish smth

eg

key(:platforms).required(:array?) { inclusion?(['facebook', 'flickr', 'linkedin', 'twitter', 'xing', 'youtube']) }

optional(:content).required(:str?)

rule(twitter_limit: [:content, :platforms]) do |content, platforms|
  (check somehow that platforms includes 'twitter' & content.filled?).then(content.max_size?(TWITTER_LIMIT))
end
I tried it with :inclusion? but thats basically from the other direction right?
I say this value must be in that array
now I want to say that array has to include that value then -> limit validation
or I'm confused again and don't see the easy approach to that :D
Benjamin Klotz
@tak1n
Apr 05 2016 09:21 UTC
also I recognize the inclusion? on platforms is wrong it should be each element of the array has to be one of these platforms

this doesn't work either

key(:platforms).required(:array?).each { inclusion?(['facebook', 'flickr', 'linkedin', 'twitter', 'xing', 'youtube']) }

I pass in platforms: ['whatever'] and its valid

Nicolas Cavigneaux
@Bounga
Apr 05 2016 09:24 UTC
Hello, I'm stuck doing a pretty simple validation involving two objects. I have an Entity that has a Type stored in typeivar
Benjamin Klotz
@tak1n
Apr 05 2016 09:25 UTC
hey @Bounga can u post the code maybe I can help u
Nicolas Cavigneaux
@Bounga
Apr 05 2016 09:25 UTC
I'd like to check that the Entity numberivar has a given format when type.name is foo
Schema = Dry::Validation.Schema do
          key(:name).required
          key(:type).schema(Ffepgv::Core::Entities::TypeEntity::Schema)

          rule(number_format: [:type, :number]) do |type, number|
            type['name'].eql?('CODEP').then(number.format?(/^D\d{3}$/))
          end
        end
I know it can't work this way but I think you can see what I want to do
to sum up, if my_object.type.name == 'CODEP'then validate that my_object.numberis something like 'D123'
Benjamin Klotz
@tak1n
Apr 05 2016 09:30 UTC
I think smth like that
SCHEMA = Dry::Validation.Schema do
  key(:name).required
  key(:number)

   rule(number_format: [:name, :number]) do |name, number|
     name.eql?('CODEP').then(number.format?(number.format?(/^D\d{3}$/))
   end
end
u have to specify number as key I think
otherwise u can not use it as a dependent value for a high level rule
Nicolas Cavigneaux
@Bounga
Apr 05 2016 09:31 UTC
that's the referenced type's name I want to check, not current object name
Benjamin Klotz
@tak1n
Apr 05 2016 09:32 UTC
oops sry yes
Piotr Solnica
@solnic
Apr 05 2016 09:32 UTC
key(:number) is not enough, it will only check if the key is present
Benjamin Klotz
@tak1n
Apr 05 2016 09:33 UTC
key(:number).required(:str?) ? :D
Nicolas Cavigneaux
@Bounga
Apr 05 2016 09:34 UTC
ultimately I want to do number.format?(/^D\d{3}$/) if type.name == 'CODEP'but it's not the way it works using dry-validation
@solnic Is it something I can do using your gem?
Piotr Solnica
@solnic
Apr 05 2016 09:37 UTC
yep
it can do everything :laughing:
This message was deleted
Schema = Dry::Validation.Schema do
  key(:name).required
  key(:type).schema(Ffepgv::Core::Entities::TypeEntity::Schema)

  rule(number_format: [[:type, :name], :number]) do |type_name, number|
    type_name.eql?('CODEP').then(number.format?(/^D\d{3}$/))
  end
end
@Bounga this should work ^
Nicolas Cavigneaux
@Bounga
Apr 05 2016 09:40 UTC
@solnic :)
Luca Guidi
@jodosha
Apr 05 2016 09:41 UTC
:D
Nicolas Cavigneaux
@Bounga
Apr 05 2016 09:41 UTC
I'll try this, thanks!
Piotr Solnica
@solnic
Apr 05 2016 09:41 UTC
you can even rely on an array element like rule(foo: [[:items, 0]]) do |first_item| …
Nicolas Cavigneaux
@Bounga
Apr 05 2016 09:42 UTC
interesting
Luca Guidi
@jodosha
Apr 05 2016 09:42 UTC
cool
Benjamin Klotz
@tak1n
Apr 05 2016 09:43 UTC

@solnic sry to bother u again, but to come back to my question above
basically I want to say (platforms.contains?('twitter') & content.filled?).then(content.max_size?(TWITTER_LIMIT)

is this somehow possible? :D

Piotr Solnica
@solnic
Apr 05 2016 09:43 UTC
@tak1n we are missing a predicate to cover your use case
Benjamin Klotz
@tak1n
Apr 05 2016 09:44 UTC
I tried to implement a custom predicate
but I don't have access to the LHS of the predicate do I?
Piotr Solnica
@solnic
Apr 05 2016 09:44 UTC
yeah it’s just a method in the configure block
def contains?(items, arr); items.all? { |item| arr.include?(item) };end or something like that
@tak1n ^^
Benjamin Klotz
@tak1n
Apr 05 2016 09:46 UTC
@solnic okay thx, will try that :)
in the examples only def whatever?(value) is used, so I was not sure how to access the element
Piotr Solnica
@solnic
Apr 05 2016 09:47 UTC
these are “functions”, so they receive all args
Benjamin Klotz
@tak1n
Apr 05 2016 09:47 UTC
okay cool
Piotr Solnica
@solnic
Apr 05 2016 09:48 UTC
type?(String) translates to def type?(klass, value) sig
Benjamin Klotz
@tak1n
Apr 05 2016 09:48 UTC
okay thx
Piotr Solnica
@solnic
Apr 05 2016 09:53 UTC
you can then do sth like platform.twitter?.then(…)
ugh, sorry my example with contains was stupid
Benjamin Klotz
@tak1n
Apr 05 2016 09:53 UTC
I'm just doing that for now:
def contains?(platform, platforms)
  platforms.include?(platform)
end
Piotr Solnica
@solnic
Apr 05 2016 09:54 UTC
I meant def contains?(val, arr); arr.include?(val); end
Benjamin Klotz
@tak1n
Apr 05 2016 09:54 UTC
no need to be sorry you helped me alot :D
Piotr Solnica
@solnic
Apr 05 2016 09:54 UTC
right right
we can add include? predicate
Benjamin Klotz
@tak1n
Apr 05 2016 09:54 UTC
yep I think I will try to form a pr
just need to get comfortable with the code :)
Luca Guidi
@jodosha
Apr 05 2016 10:37 UTC
@tak1n I'm curious, why inclusion? doesn't work for you?
Nicolas Cavigneaux
@Bounga
Apr 05 2016 10:39 UTC
@solnic seems like there's still something to do for your example to work. With the validation schema you gave me, I get NoMethodError: undefined methodsuccess?' for "foo":String`
foo is the value I provided for type.name
hum 1 se c
maybe my fault
nope
#<Ffepgv::Core::Entities::Entity:0x007faf71938910 @ref=nil, @name="lk", @number="D123", @locality=nil, @way="Bastille", @residence=nil, @zipcode="62210", @city="Avion", @phone=nil, @mobile=nil, @email=nil, @website=nil, @type={:name=>"foo"}>
Nicolas Cavigneaux
@Bounga
Apr 05 2016 10:49 UTC
Schema.call({type: {name: "foo"}})
this is enough to reproduce the problem
Benjamin Klotz
@tak1n
Apr 05 2016 11:00 UTC

@jodosha I tried :inclusion? with following code:

key(:platforms).required(:array?) { inclusion?(['facebook', 'flickr', 'linkedin', 'twitter', 'xing', 'youtube']) }

optional(:content).required(:str?)

rule(twitter_limit: [:content, :platforms]) do |content, platforms|
  (platforms.inclusion?('twitter') & content.filled?).then(content.max_size?(TWITTER_LIMIT))
end

But as the example in http://dry-rb.org/gems/dry-validation/basics/built-in-predicates/ states:

inclusion?

Checks that a value is included in a given array.

The problem is I want to check if my array contains a value, sure this could be argumented as checking that a value is included in a given array, but it doesn't work:

'twitter'.inclusion?(platforms)

This will raise an exception (undefind method inclusion? on String)

Piotr Solnica
@solnic
Apr 05 2016 11:07 UTC
inclusion? is for a value that must be of specified values
Benjamin Klotz
@tak1n
Apr 05 2016 11:29 UTC

@solnic I basically got everything working, now I'm trying to use macros instead of block syntax where possible:

require 'dry/validation'

SCHEMA = Dry::Validation.Schema do
  key(:platforms) { array? { filled? { each { inclusion?(%w(facebook flickr linkedin twitter xing youtube)) } } } }
end

SCHEMA_2 = Dry::Validation.Schema do
  key(:platforms).each { inclusion?(%w(facebook flickr linkedin twitter xing youtube)) }
end


result  = SCHEMA.call(platforms: 'not_an_array')
result2 = SCHEMA_2.call(platforms: 'not_an_array')
p result.messages
p result2.messages

result  = SCHEMA.call(platforms: ['facebook', 'whatever', 'whatelse'])
result2 = SCHEMA_2.call(platforms: ['facebook', 'whatever', 'whatelse'])
p result.messages
p result2.messages

result  = SCHEMA.call(platforms: [])
result2 = SCHEMA_2.call(platforms: [])
p result.messages
p result2.messages

results in

{:platforms=>["must be an array", "must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}
{:platforms=>["must be an array", "must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}
{:platforms=>{1=>["must be one of: facebook, flickr, linkedin, twitter, xing, youtube"], 2=>["must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}}
{:platforms=>{1=>["must be one of: facebook, flickr, linkedin, twitter, xing, youtube"], 2=>["must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}}
{:platforms=>["must be filled", "must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}
{}

Is there a way to chain macros?
basically what I want to say is key(:platforms).required(:array?).each { inclusion?(...) }

When doing that I get following results:
{:platforms=>["must be an array", "must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}
{:platforms=>["must be an array"]}
{:platforms=>{1=>["must be one of: facebook, flickr, linkedin, twitter, xing, youtube"], 2=>["must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}}
{}
{:platforms=>["must be filled", "must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}
{:platforms=>["must be filled"]}
which is not what I wanted todo :D
it should check for filled in yes but still should check inclusion of
Piotr Solnica
@solnic
Apr 05 2016 11:37 UTC
@tak1n why not: key(:platforms).each(:filled?, :inclusion?(%w(facebook flickr linkedin twitter xing youtube)) ??
@Bounga do you have a validation rule for name?
Benjamin Klotz
@tak1n
Apr 05 2016 11:40 UTC
@solnic thats not valid ruby syntax or?
and I don't want to check filled on each element I want to check filled on the array or I don't get it :D
Nicolas Cavigneaux
@Bounga
Apr 05 2016 11:44 UTC
@solnic you mean for type's name?
Piotr Solnica
@solnic
Apr 05 2016 11:45 UTC
@tak1n wdym? of course it is
each is just a method
Nicolas Cavigneaux
@Bounga
Apr 05 2016 11:45 UTC
I do have one on the main object's name (required) and the same one in for type's name
Piotr Solnica
@solnic
Apr 05 2016 11:46 UTC
@tak1n well, you can skip filled? and each implies array? check anyway and it’s set automatically
Benjamin Klotz
@tak1n
Apr 05 2016 11:46 UTC
@solnic I mean the :inclusion(..) thing
test.rb:8: syntax error, unexpected '(', expecting ')'
...ms).each(:filled?, :inclusion?(%w(facebook flickr linkedin t...
...                               ^
test.rb:8: syntax error, unexpected ')', expecting keyword_end
...linkedin twitter xing youtube)))
...                               ^
test.rb:28: syntax error, unexpected end-of-input, expecting keyword_end
require 'dry/validation'

SCHEMA = Dry::Validation.Schema do
  key(:platforms) { array? { filled? { each { inclusion?(%w(facebook flickr linkedin twitter xing youtube)) } } } }
end

SCHEMA_2 = Dry::Validation.Schema do
  key(:platforms).each(:filled?, :inclusion?(%w(facebook flickr linkedin twitter xing youtube)))
end


result  = SCHEMA.call(platforms: 'not_an_array')
result2 = SCHEMA_2.call(platforms: 'not_an_array')
p result.messages
p result2.messages

result  = SCHEMA.call(platforms: ['facebook', 'whatever', 'whatelse'])
result2 = SCHEMA_2.call(platforms: ['facebook', 'whatever', 'whatelse'])
p result.messages
p result2.messages

result  = SCHEMA.call(platforms: [])
result2 = SCHEMA_2.call(platforms: [])
p result.messages
p result2.messages
Luca Guidi
@jodosha
Apr 05 2016 11:48 UTC
@tak1n that should be inclusion?: %w(...)
Benjamin Klotz
@tak1n
Apr 05 2016 11:48 UTC
also tried with key(:platforms).each(:filled?, inclusion?: %w(facebook flickr linkedin twitter xing youtube))
/home/benny/Dev/onlim/adapter/.gem/ruby/2.3.0/gems/dry-validation-0.7.3/lib/dry/validation/schema/value.rb:40:in `block in each': [:inclusion?, ["facebook", "flickr", "linkedin", "twitter", "xing", "youtube"]] is not a symbol nor a string (TypeError)
        from /home/benny/Dev/onlim/adapter/.gem/ruby/2.3.0/gems/dry-validation-0.7.3/lib/dry/validation/schema/value.rb:40:in `each'
        from /home/benny/Dev/onlim/adapter/.gem/ruby/2.3.0/gems/dry-validation-0.7.3/lib/dry/validation/schema/value.rb:40:in `reduce'
        from /home/benny/Dev/onlim/adapter/.gem/ruby/2.3.0/gems/dry-validation-0.7.3/lib/dry/validation/schema/value.rb:40:in `each'
        from /home/benny/Dev/onlim/adapter/.gem/ruby/2.3.0/gems/dry-validation-0.7.3/lib/dry/validation/schema/rule.rb:40:in `each'
        from test.rb:8:in `block in <main>'
        from /home/benny/Dev/onlim/adapter/.gem/ruby/2.3.0/gems/dry-validation-0.7.3/lib/dry/validation.rb:23:in `instance_exec'
        from /home/benny/Dev/onlim/adapter/.gem/ruby/2.3.0/gems/dry-validation-0.7.3/lib/dry/validation.rb:23:in `Schema'
        from test.rb:7:in `<main>'
Luca Guidi
@jodosha
Apr 05 2016 11:52 UTC
@tak1n isn't filled?redundant? In my understanding that is going to check if each single element is not empty. But that is already ensured by the inclusion clause. An empty string isn't a value that allowed in that set.
Benjamin Klotz
@tak1n
Apr 05 2016 11:54 UTC
@jodosha yep, thats true
but I wanted to check filled on the array but I'm no longer sure if I even need to do that :D
Nicolas Cavigneaux
@Bounga
Apr 05 2016 11:55 UTC
@solnic Is it a normal behavior to you that success? is called on type.name's value? https://github.com/dry-rb/dry-validation/blob/master/lib/dry/validation/schema_compiler.rb#L22
Benjamin Klotz
@tak1n
Apr 05 2016 11:57 UTC

@jodosha and it seems I have to check filled? on array:

key(:platforms).each { inclusion?(%w(facebook flickr linkedin twitter xing youtube)) }

results in

{:platforms=>"not_an_array"}
{:platforms=>["must be an array", "must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}

{:platforms=>["facebook", "whatever", "whatelse"]}
{:platforms=>{1=>["must be one of: facebook, flickr, linkedin, twitter, xing, youtube"], 2=>["must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}}

{:platforms=>[]}
{}
the last example would pass validation altough an empty array was given
Luca Guidi
@jodosha
Apr 05 2016 11:58 UTC
@tak1n I would have expected this syntax to work:
key(:platforms).required(:filled?, :array?).each { inclusion?( %w(twitter) ) }
@tak1n The first part works:
irb(main):028:0> schema.call({})
=> #<Dry::Validation::Result output={} messages={:platforms=>["is missing"]}>
irb(main):029:0> schema.call({platforms: 1})
=> #<Dry::Validation::Result output={:platforms=>1} messages={:platforms=>["must be an array"]}>
@tak1n but the latter won't:
irb(main):030:0> schema.call({platforms: [1]})
=> #<Dry::Validation::Result output={:platforms=>[1]} messages={}>
Benjamin Klotz
@tak1n
Apr 05 2016 12:00 UTC
@jodosha :required already expands to: key(:age) { filled? }
# expands to `key(:age) { filled? & int? }`
key(:age).required(:int?)
and that was exactly what I did before, I tried to chain the macros required and each :D
Piotr Solnica
@solnic
Apr 05 2016 12:01 UTC
Yeah that is one of the reasons we are thinking about renaming things
Benjamin Klotz
@tak1n
Apr 05 2016 12:02 UTC

but then like u said @jodosha:

key(:platforms).required(:array?).each { inclusion?(%w(facebook flickr linkedin twitter xing youtube)) }

breaks the inclusion validation

{:platforms=>"not_an_array"}
{:platforms=>["must be an array"]}

{:platforms=>["facebook", "whatever", "whatelse"]}
{}

{:platforms=>[]}
{:platforms=>["must be filled"]}
I think for now I just keep the block syntax I had working :D
but thx for help @jodosha and @solnic :clap:
Luca Guidi
@jodosha
Apr 05 2016 12:04 UTC
@tak1n key(:platforms){ filled? & type?(Array) & array? { each { inclusion? %w(twitter) } } }, but it breaks :(

@solnic

Yeah that is one of the reasons we are thinking about renaming things

:scream_cat: :scream: :scream_cat:

Benjamin Klotz
@tak1n
Apr 05 2016 12:06 UTC
@jodosha:
key(:platforms) { filled? { array? { each { inclusion?(%w(facebook flickr linkedin twitter xing youtube)) } } } }
{:platforms=>"not_an_array"}
{:platforms=>["must be an array", "must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}

{:platforms=>["facebook", "whatever", "whatelse"]}
{:platforms=>{1=>["must be one of: facebook, flickr, linkedin, twitter, xing, youtube"], 2=>["must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}}

{:platforms=>[]}
{:platforms=>["must be filled", "must be one of: facebook, flickr, linkedin, twitter, xing, youtube"]}
Luca Guidi
@jodosha
Apr 05 2016 12:10 UTC
@tak1n :+1:
Nicolas Cavigneaux
@Bounga
Apr 05 2016 12:12 UTC
@solnic I created a minimalistic Gist to demonstrate the issue. Maybe it can help you to help me out https://gist.github.com/Bounga/36875ef3201d2406821c9d48f5890874
So if I run this, I end up with /usr/local/var/rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/dry-validation-0.7.3/lib/dry/validation/schema_compiler.rb:22:inblock in deps_valid?': undefined method success?' for "CODEP":String (NoMethodError)
Piotr Solnica
@solnic
Apr 05 2016 12:25 UTC
inclusion? is not for arrays
it’s for a value that must be one of other values, just like in AM::V
you basically want to check if an array includes one or more of the known values
Benjamin Klotz
@tak1n
Apr 05 2016 12:27 UTC
@solnic but thats exactly what I wanted to know or? :D
I have a platforms array and want to know if it includes 'twitter'
so I should be able to use :inclusion?
Piotr Solnica
@solnic
Apr 05 2016 12:29 UTC
you want to validate if it has one or more of the known values, and THEN you want to do the matching on which value it actually includes
Benjamin Klotz
@tak1n
Apr 05 2016 12:29 UTC
true
Piotr Solnica
@solnic
Apr 05 2016 12:29 UTC
you can’t use inclusion? for the matching, it needs the new predicate
Benjamin Klotz
@tak1n
Apr 05 2016 12:29 UTC
yep makes sense now, thx :clap:
Piotr Solnica
@solnic
Apr 05 2016 12:30 UTC
@Bounga thanks, I’ll look into that when I have some time
Nicolas Cavigneaux
@Bounga
Apr 05 2016 12:31 UTC
@solnic Thank you
Jules Ivanic
@guizmaii
Apr 05 2016 14:06 UTC

Hi everyone,

I just discovered dry-types because I was searching a way to express optional things with virtus. I think it's a great work (as always with @solnic ! congratulations dude ! You make me like Ruby while I dislike it and dynamic languages in general).

With Virtus in an old Rails project, I defined a domain object name Assignment like this:

  class Assignment
    include Virtus.value_object

    attribute :delivery, Delivery
    attribute :carrier, Carrier
    attribute :created_at, Time
  end

Where Delivery and Carrier are Rails model.
Now with dry-types, I changed my code like that:

  class Assignment < Dry::Types::Struct
    attribute :delivery, Delivery
    attribute :carrier, Carrier
    attribute :created_at, Types::Maybe::Strict::Time
  end

But my tests passed red because: Nothing registered with the key "delivery" (Dry::Container::Error).
How can I fix this ?

Andy Holland
@AMHOL
Apr 05 2016 14:25 UTC
@guizmaii the best way would probably be to change all of your virtus classes to dry-types structs
require 'dry-types'

module Types
  include Dry::Types.module
end

class Delivery < Dry::Types::Struct
  attribute :reference, Types::Strict::String
end

class Carrier < Dry::Types::Struct
  attribute :name, Types::Strict::String
end

class Assignment < Dry::Types::Struct
  attribute :delivery, Delivery
  attribute :carrier, Carrier
  attribute :created_at, Types::Maybe::Strict::Time
end

Assignment.new(delivery: { reference: '1337' }, carrier: { name: 'O2' }, created_at: nil)
=> #<Assignment delivery=#<Delivery reference="1337"> carrier=#<Carrier name="O2"> created_at=None>
Jules Ivanic
@guizmaii
Apr 05 2016 14:32 UTC
Hum I don't really know if it's possible because, for example, my Delivery class is defined like this:
class Delivery < ActiveRecord::Base
...
end
I don't really need to valid anything on Delivery or Carrier. Just that they are some Delivery or Carrier
Andy Holland
@AMHOL
Apr 05 2016 14:46 UTC
Sorry, just figuring it out myself =P
@guizmaii this works:
require 'dry-types'

class Delivery
  attr_reader :reference

  def initialize(attributes)
    @reference = attributes.fetch(:reference)
  end
end

class Carrier
  attr_reader :name

  def initialize(attributes)
    @name = attributes.fetch(:name)
  end
end

module Types
  include Dry::Types.module

  [Delivery, Carrier].each do |primitive|
    self.const_set(
      primitive.to_s,
      Dry::Types::Definition[primitive].new(primitive).constructor { |input|
        primitive.new(input)
      }
    )
  end
end

class Assignment < Dry::Types::Struct
  attribute :delivery, Types::Delivery
  attribute :carrier, Types::Carrier
  attribute :created_at, Types::Maybe::Strict::Time
end

Assignment.new(delivery: { reference: '1337' }, carrier: { name: 'O2' }, created_at: nil)
# => #<Assignment delivery=#<Delivery:0x0056053a1aaeb0 @reference="1337"> carrier=#<Carrier:0x0056053a1aae60 @name="O2"> created_at=None>
Luca Guidi
@jodosha
Apr 05 2016 15:49 UTC
Folks, @solnic mentioned that the public API is gonna change. Probably it's a matter of renaming methods. Is that correct?
Nicolas Cavigneaux
@Bounga
Apr 05 2016 15:57 UTC
That's what I understood
Luca Guidi
@jodosha
Apr 05 2016 16:02 UTC
@Bounga Is that an answer to my question? :)
Nicolas Cavigneaux
@Bounga
Apr 05 2016 16:13 UTC
@jodosha Sorry yes, I saw him saying that some change were needed to clarify things. I think it's renaming
Luca Guidi
@jodosha
Apr 05 2016 16:13 UTC
@Bounga Thanks!
Benjamin Klotz
@tak1n
Apr 05 2016 16:40 UTC
@jodosha: dry-rb/dry-validation#90
Luca Guidi
@jodosha
Apr 05 2016 16:41 UTC
@tak1n thanks!
Benjamin Klotz
@tak1n
Apr 05 2016 16:41 UTC
np :)
There's also a comment there for automagically registering your AR classes with dry-types
Tim Riley
@timriley
Apr 05 2016 21:35 UTC
Nice one, @AMHOL
Andy Holland
@AMHOL
Apr 05 2016 21:37 UTC
:joy:
@timriley did you record the talk? :)
Tim Riley
@timriley
Apr 05 2016 22:05 UTC
Alas, I forgot :weary:
Next time! I’m going to make another version of this talk that incorporates dry-web, and aims to talk about things more conceptually than at a fine detail level.
That’ll be the one to record.
John Backus
@backus
Apr 05 2016 22:25 UTC
@solnic ping re: dry-rb/dry-types#70
I'm more immediately interested in whether you agree with what I'm talking about in that PR (also for dry-rb/dry-types#71) than getting it merged
I also have a separate issue I want to open regarding Dry::Types::Struct constructors which is more design-y but I wanted to clear this discussion first before building on it
John Backus
@backus
Apr 05 2016 22:51 UTC
Also unrelated: it would be better if requiring dry-types didn't monkey patch Object
Andy Holland
@AMHOL
Apr 05 2016 23:12 UTC
@backus where does it monkey patch Object?
Is it a dependency?
Tim Riley
@timriley
Apr 05 2016 23:18 UTC
Perhaps referring to txus/kleisli#17 ?
Which AFAIK is fixed but not yet released.
John Backus
@backus
Apr 05 2016 23:37 UTC
Yes kleisli
Tim Riley
@timriley
Apr 05 2016 23:37 UTC
Perhaps you could chime in on that issue and also ask kindly for a release? :)
John Backus
@backus
Apr 05 2016 23:42 UTC
done