Can someone give me an example of how this can be done? OR how I should be reading these values (0/1) from the database to have them represented by ruby false and true?
Thanks!
Can someone give me an example of how this can be done? OR how I should be reading these values (0/1) from the database to have them represented by ruby false and true?
Thanks!
You can use a custom read type, ie attribute :admin, Types::Integer, read: Types::Params::Bool
Thanks! This works of course, but it is unclear why it works. The dry types state
params
- types with constructors performing non-strict coercions specific to HTTP parameters
Why use the Params type category over others when reading from the db?
In this case, because Params
does the loose type coercion that you need for numeric booleans.
By default, dry-types is strict about type checking. Try it and see:
Types::Strict::Bool[1]
# => Dry::Types::ConstraintError: 1 violates constraints (type?(FalseClass, 1) failed)
An integer is not a boolean in Ruby, and you don’t want that to be the case most of the time. Ruby is a strongly typed language, and so if you intend to convert a number to a boolean it should be done explicitly.
Interacting with a different type system is a special case, and Params
is there to do those kind of coercions. It’s not specifically meant for databases, but it works here.
In more advanced cases, you might want to define your own coercion rules for custom types. For instance, this boolean coercion might be written as
Bool = Types::Strict::Bool.constructor do |input, type|
case input
when true, 1, 't', 'TRUE' then true
when false, 0, 'f', 'FALSE' then false
else type.(input)
end
Thank you kindly for your detail response. This is helpful!