Check error message
Call to private method Payment::before_save() from context 'Record'
This means that you are trying to call the function defined in Payment while you are within Record . The Record class does not have a before_save method, because it is more up in the inheritance chain than where the function is defined.
In other words, since the parent-child relationship is Record (is parent of) Payment , Payment has access to the Records functions (due to inheritance from the parent), but not vice versa (the parent cannot "inherit" the child class of the function). You can protect your function, which will give it access up and down the inheritance chain, but you may want to rethink the architecture and decide whether you want it. Ideally, you should have a function defined in Record and override it in Payment
Also (and maybe I'm wrong), but checking explicitly for method_exists usually not required unless you are creating a truly dynamic system where runtime classes can overlap and / or be generated. If you define a class-based system from scratch, and you know how you stitch the various parts together, you usually will not need to check at runtime if method_exists ... just a thought ..
source share