Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
Ryan Bigg
@radar
in ur repos, submitting PRs: dry-rb/dry-core#25
Jonah
@jonahx

How can I mix required and optional/default attributes? That is, the following works fine:

class Test < Dry::Struct
  attribute :optional, Types::Any.default('default value')
end
p Test.new.optional #=> prints 'default value'

However

class Test2 < Dry::Struct
  attribute :required, Types::Any
  attribute :optional, Types::Any.default('default value')
end
p Test2.new(required: 'my required val')
# Raises:
# [Test2.new] :optional is missing in Hash input (Dry::Struct::Error)
Jean-Denis Koeck
@jeandenis-k
Hi @jonahx ! Seems to me you would have to use, in the body of your class, either constructor_type :strict_with_defaults or constructor_type :schema
Jonah
@jonahx
@jeandenis-k thanks, i’ll try it
Jean-Denis Koeck
@jeandenis-k
:+1:
Jonah
@jonahx
Separate question. Consider:
class Test < Dry::Struct
  attribute :cls, Types::Any.default(String)
end

p Test.new.cls == String # return true
Yet in my actual code I’m doing the same thing with a Sequel class:
    attribute :resource_class, ::Types::Any.default(Resource)
but when I later access resource_class it returns not the class, but it seems an instance of the class:
#<Resource @values=#<#<Class:0x00000003e7bf00> primitive=Object options={} meta={}>>
Is there any magic the dry::struct does on class values for defaults that would explain this?
Jonah
@jonahx

Interesting…
The problem is fixed if I do

attribute :resource_class, ::Types::Any.default { Resource }

I wonder why those are different?

Jean-Denis Koeck
@jeandenis-k
Interesting, tried to find why in the source code of dry-types but I can't make head or tails of it :sweat_smile:
Andrea Tore
@nakedmoon
Hi guys, quick question: is there any way to have a dry-struct attribute like a Constructor Types::Hash with a default value ?
Andrea Tore
@nakedmoon
IntType = Types.Constructor(Types::Hash){|value| Types::Hash(:strict_with_defaults, int: Types::Form::Int)[int: value]}

class MyClass < Dry::Struct
constructor_type :strict_with_defaults
Andrea Tore
@nakedmoon
IntType = Types.Constructor(Types::Hash){|value| Types::Hash(:strict_with_defaults, int: Types::Form::Int)[int: value]}

class MyClass < Dry::Struct
  constructor_type :strict_with_defaults
  attribute int_attribute_one, Types::IntType.default(1)
  attribute int_attribute_two, Types::IntType.default(2)
end

2.3.3 :181 > MyClass.new()
TypeError: class or module required

using the block notation:

attribute int_attribute_one, Types::IntType.default{1}
attribute int_attribute_two, Types::IntType.default{2}

2.3.3 :188 > MyClass.new()
=> #<MyClass int_attribute_one={:int=>1} int_attribute_two={:int=>2}>
2.3.3 :189 > MyClass.new(int_attribute_one: 1)
=> #<MyClass int_attribute_one={:int=>1} int_attribute_two=2>
Nikolai Budko
@nibygro

Hi guys! I have a problem with dry-validations (0.11)

require 'dry-validation'

UserSchema = Dry::Validation.Schema do
  rule(value_filled: [:value1, :value2, :value3]) do |value1, value2, value3|
    value1.eql?('1') | value2.eql?('1') | value3.eql?('1')
  end
end

UserSchema.(
  value1: '0',
  value2: '0',
  value3: '0'
).inspect

# => "#<Dry::Validation::Result output={:value1=>\"0\", :value2=>\"0\", :value3=>\"0\"} errors={}>"

Why there are no errors for the schema? y rule is one of the fields must be filled with '1'

Nikolai Budko
@nibygro

Oh, I'v got it. I need to defined this properies as optional

But I think it's a little bit redundant..

Also if I define three optional properties, than I will get a strange error:
 => "#<Dry::Validation::Result output={:value1=>\"0\", :value2=>\"0\", :value3=>\"0\"} errors={:some_filled=>[\"must be equal to 1 or must be equal to 1\"]}>"
Ryan Bigg
@radar
dry-rb/dry-equalizer#9 I don't understand how / why this is different from dry-rb/dry-equalizer#8 but there you go. So very perplexed.
Turns out: I don't know Ruby.
Joshua Hansen
@binarypaladin
I can't tell if I've hit a bug or I'm using some kind of behavior incorrectly, but it seems to me there are oddities when using schema inheritance with schemas that are create with JSON or Form. Consider this:
Schema = Dry::Validation.Schema do
  configure { config.type_specs = true }
  required(:first_name, :string).filled(:str?)
end

OtherSchema = Dry::Validation.Schema(Schema) do
  required(:last_name, :string).filled(:str?)
end

input = { first_name: 'John', last_name: 'Smith' }
Schema.(input).success? => true
Schema.(input).output => {:first_name=>"John", :last_name=>"Smith"}
OtherSchema.(input).success? => true
OtherSchema.(input).output => {:first_name=>"John", :last_name=>"Smith"}

Schema = Dry::Validation.JSON do
  configure { config.type_specs = true }
  required(:first_name, :string).filled(:str?)
end

OtherSchema = Dry::Validation.Schema(Schema) do
  required(:last_name, :string).filled(:str?)
end

input = { 'first_name' => 'Joe', 'last_name' => 'Smith' }

Schema.(input).success? => true
Schema.(input).output => {:first_name=>"Joe"}
OtherSchema.(input).success? => false
OtherSchema.(input).errors => {:first_name=>["is missing"]}
I cannot seem seem to get OtherSchema to recognize first_name. Inheritance works as I would expect with the normal schema. It's not a problem with the JSON macro either, as this would yield the same issues:
Schema = Dry::Validation.Schema do
  configure do
    config.type_specs = true
    config.input_processor = :json
    config.hash_type = :symbolized
  end
  required(:first_name, :string).filled(:str?)
end

OtherSchema = Dry::Validation.Schema(Schema) do
  required(:last_name, :string).filled(:str?)
end
I thought perhaps explicitly setting configuration on both would do the trick, but no dice:
OtherSchema = Dry::Validation.Schema(Schema) do
  configure do
    config.type_specs = true
    config.input_processor = :json
    config.hash_type = :symbolized
  end
  required(:last_name, :string).filled(:str?)
end
Joshua Hansen
@binarypaladin
Setting input_processor is clearly the culprit when messing around with scenarios.
Any ideas on how to handle inheritance with with a preprocessor set?
Joshua Hansen
@binarypaladin

One more thing to add, it isn't just the input_preprocessor but rather a combination of that and type_specs set to true. Looking at OtherSchema I see that:

OtherSchema.config[:type_map] => {:last_name=>#<Dry::Types::Definition primitive=String options={} meta={}>}

Not that first_name is not in the type_map. I haven't done a deep dive into the code yet, but if anyone familiar with the finer points can give me any pointers (or just flat out tell me if this is a bug and, if so, I'll work to patch it) that would be really handy.

Joshua Hansen
@binarypaladin

Looks like the bug has actually been patched: https://github.com/dry-rb/dry-validation/pull/359/commits/71872da3985c54b6930ed39c42d004f837e9812f

This fixes the behavior. Is there something wrong with this PR?

if you want to use them with dry-validation, please stick to the master branch for now
Chris Richards
@cmrichards
hmm.. get this error in the rails console but the code works just fine when running the server: "LoadError (cannot load such file -- dry-struct)"
Nikita Shilnikov
@flash-gordon
what's the stacktrace?
Damien Timewell
@idlefingers
Hey guys, I'm upgrading a project I'm working on to the most recent dry-types and dry-struct and trying to understand how to deal with the removal of constructor_type. Can someone point me in the direction of how to make all attributes omittable, without explicitly having to set .meta(omittable: true)? I used constructor_type :schema to get around it before..
Gustavo Caso
@GustavoCaso
Hi @idlefingers
I think this will do the trick
class User < Dry::Struct
  transform_types do |type|
    type.meta(omittable: true)
  end

  attribute :name, Types::Strict::String
  attribute :age,  Types::Strict::Integer.default(18)
end
Please let me know if that solved the problem
Damien Timewell
@idlefingers
Ahaaaa, I get it. It works! Perfect, thanks a ton for your help @GustavoCaso :)
Gustavo Caso
@GustavoCaso
My pleasure :smile:
Damien Timewell
@idlefingers
Hmmm, but now the meta is included in Hash values :/ ...
class User < Dry::Struct
  transform_types do |type|
    type.meta(omittable: true)
  end

  attribute :foo, Types::Hash.default(Hash.new)
end
User.new.foo # => {:meta=>{:omittable=>true}}
Gustavo Caso
@GustavoCaso
class User < Dry::Struct
  transform_types do |type|
    type.optional
  end

  attribute :name, Types::Strict::String
  attribute :age,  Types::Strict::Integer.default(18)
end
Could you try that one?
Damien Timewell
@idlefingers
That just means it can be nil, but the key is still required, right?
Dry::Struct::Error: [User.new] :name is missing in Hash input
Gustavo Caso
@GustavoCaso
You can set a deafult value if what you are looking is for avoid the meta
Does it helps you? @idlefingers
Damien Timewell
@idlefingers
I'm not sure I follow. In the example class I pasted above, I set the default to be a new hash, but when the class is initialized, that hash includes became {:meta=>{:omittable=>true}}
so instead of User.new.foo # => {:meta=>{:omittable=>true}} I'm trying to get User.new.foo # => {} (which is what constructor_type :schema did before)
Gustavo Caso
@GustavoCaso
All your attributes are hashes?
class User < Dry::Struct
  transform_types do |type|
    type.optional.deafult({})
  end

  attribute :foo, Types::Hash
end