Strict mode only works for basic values
require 'virtus'
class SomeRandomClass
end
class User
include Virtus.model(strict: true)
attribute :some_ran_class, SomeRandomClass
end
User.new(some_ran_class: 5) # no error
User.new() # no error
User.new(some_ran_class: SomeRandomClass.new) # should be the only one that doesn't cause an error
This is because if the type is not a recognized primitive, it defaults to Object, and coercing an object to an object will always work.
But I feel like if you have strict mode enabled, you should only be able to have the Class type you specified
Just came across this - what's the sense of specifying attribute type if that type isn't honored? That's a total disaster. You can assign random things to attribute and there's no casting done when you supply virtus model #new with a hash of stuff.
@celesteking you should check out https://github.com/AaronLasseigne/active_interaction
It’s a much better implementation
Me? Nope, because it's 3rd party (elasticsearch-persistence) that's using this stale software. Anyways, I've managed to find a workaround:
require 'ipaddr'
class Mymodel
include Virtus.model
class TypeCoercer
define_singleton_method(:[]) do |cast_type|
Class.new(Virtus::Attribute).class_eval do
define_method(:coerce) do |value|
value && cast_type.new(value)
end
self
end
end
end
attribute :myattr, TypeCoercer[IPAddr], default: nil
end
puts Mymodel.new(myattr: '1.2.3.4').myattr.class
VIRTUS CUSTOM COERCION NOT WORKING attribute not coercing