Overriding setter method after attr_accessor in Rails
I just stumbled across a mean little detail when using attr_accessor in Rails. The situation is as follows:
- I have a concern (a module) that I include in my model class
- The concern defines an
attr_accessor
- The concern overrides the setter of the
attr_accessor
The (wrong!) code
The problem
If you try using this, your user_fees=
method will never be called!
The reason
As explained in https://stackoverflow.com/a/8043553/704499 this happens due to the order in which Ruby initializes these methods. It starts with instance methods and then proceeds to methods of included modules and super classes. That is why the user_fees=
method is initialized first and then directly overridden by the attr_accessor
‘s user_fees=
method!
The solution
The solution is simple. Just define an attr_reader
instead of a full accessor. Then, in your custom user_fees=
method set the instance variable directly:
(Another solution would’ve been to simply move the attr_accessor
out of the included
block. That way the initialization order would be as expected.)
The learning
If you’ve been banging your head into a wall for too long, check the initialization order or the underlying language or framework — it might be the reason for your problem. Although initialization order should not make a difference, there are edge cases that designers of a language or framework simply cannot work around.
Cheers and happy coding!