Background:
ActiveType::Object
inherits from ActiveRecod::Base
and is designed to behave like an ActiveRecord Object, just without the database persistence.
Don't remove any of the default behavior of the initialize method!
If you have a class which inherits from ActiveType::Object
and you need to override the #initialize
method, then you should be really careful:
- Always pass exactly one attribute.
ActiveRecod::Base
objects really want to get their arguments processable as keyword arguments. Don't change the syntax, or you'll experience pain. - Always call super inside of your overridden
#initialize
method. A lot of magic things happen in the ActiveRecord world. Just let them happen, otherwise kittens will die somewhere. You don't want that.
Example
class Item < ActiveType::Object
def initialize(attributes)
super
# Now, as the ActiveRecod::Base part could do it's duty, I can freely do whatever I want.
end
end
Example pitfall
- If you don't run the
super
method inside#initialize
, the object is marked as frozen. Rspec mocks (e.g. using partial doubles withreceive(partial_double).to ...
) in tests would raise the following error (just imagine how hard debugging can be):
ArgumentError:
Cannot proxy frozen objects, rspec-mocks relies on proxies for method stubbing and expectations.
- If you define
initialize
with no argument and don't call super, initialize might be hit with this error:
ArgumentError:
Wrong number of arguments (given 1, expected 0)
Further readings
Posted by Jakob Scholz to makandra dev (2022-10-18 13:29)