Closed waiting-for-dev closed 5 years ago
I reported #528 which covers the part of configuring a custom struct compiler class. Could you update the description here and provide an example of the API where you define how nullable values should be treated?
I reported #528 which covers the part of configuring a custom struct compiler class.
@solnic thanks, #528 looks great!
Could you update the description here and provide an example of the API where you define how nullable values should be treated?
Actually, I'm not 100% sure about how we should tackle it. What I want is to be able to process how optional types should be treated, no mind if they are an optional attribute or a belongs_to
or has_one
relation. If this needs to be done in rom's struct compiler, maybe something like this would be fine:
class MyStructCompiler < StructCompiler
do_with_optional -> (type) { type.maybe }
end
But I wonder if this could be done at dry-struct
or even dry-types
level...
@waiting-for-dev I believe this is something that could be done via transform_types
in Dry::Struct
. See dry-struct recipes.
Thanks for your tip @solnic . However, I think it doesn't fulfill the feature:
require 'dry/types'
require 'dry/struct'
require 'dry/monads/maybe'
class Foo < Dry::Struct
transform_types do |type|
if type.optional?
type.constructor do |value|
Dry::Monads::Maybe.coerce(value)
end
else
type
end
end
attribute :foo1, Dry::Types['strict.string'].optional
end
Foo.new(foo1: nil)
# => [Foo.new] nil (NilClass) has invalid type for :foo1 violates constraints (type?(String, None) failed) (Dry::Struct::Error)
The type remains being a Dry::Types['strict.string'].optional
, so it crashes when the value is transformed to Dry::Monads::Maybe::None
(and same for Dry::Monads::Maybe::Some
).
I first tried transforming the type itself, which seems the appropriate thing to do, but then I always get nil
not sure why:
class Foo < Dry::Struct
transform_types do |type|
type.optional? ? type.right.maybe : type
end
attribute :foo1, Dry::Types['strict.string'].optional
end
puts Foo.new(foo1: nil).foo1.inspect
# => nil
puts Foo.new(foo1: "a").foo1.inspect
# => nil
This is fixed by https://github.com/dry-rb/dry-types/pull/329
Thanks @flash-gordon for your quick action.
This is super neat! I don't need to configure anything in the struct compiler. I just have to create a parent struct with the transform_types
stuff and inherit all my entities from it. @solnic, I guess #528 can still be useful for other scenarios, but this issue can be closed.
Thanks for all your help.
Be able to change the way that the struct compiler treats nullable values from the datastore. Right now, they end up being whether
nil
or an actual value. It would be nice to have it being configurable, for example, to translate them into theDry::Monads::Maybe
type.For that, I would:
Examples
Resources