Forum OpenACS Q&A: Re: A doubt about Xotcl Acs objects inheritance

Posted by Neophytos Demetriou on
When one is updating an existing object though, this doesn't stand anymore: the save method in ::xo::db::Object doesn't call an analogous 'update' method. The update query is generated instead at startup as a method of my subclass. If I redefine it, then call 'next', my object's table ends up untouched, except for my specific logic that overwrote the original 'save' method.

You are right in the sense that it would have been more convenient to have an extra layer of redirection, i.e. call an analogous update method. When you subclass ::xo::db::Object you can redefine the save method. The only problem I see is that ::xo::db::Class->init can overwrite the save method in the derived class with the one that ::xo::db::Class->mk_save_method generates.

Is there a particular reason for this different behavior between inserting and updating?

The save method that is generated by ::xo::db::Class->mk_save_method calls next within a db_transaction statement (see 05-db-procs.tcl). As the code stands, that next statement invokes ::xo::db::Object->save, which is responsible for inserting the corresponding row in the acs_objects table. This works well for most cases but not when you want to add your own logic to the 'update' method or work outside of the acs_objects system.

Posted by Antonio Pisano on
Thanks for the additional insights Neophytos.

Maybe there is space for some discussion about this. I think one should expect generic logic to be inherited when using next, rather than be wiped out by specific method definition.

Here on OpenACS, I think the only class who redefined the save method is CrItem. The method is completely overwritten there, meaning that no use of the 'next' idiom is done. This is becuse CrItems need some really specific behavior to handle revisions and such.

Of course there could be people out there who wrote code with current behavior in mind and used 'next' in their 'save' implementation. If we just turn on inheritance, they will end up with code updating their objects twice... could not be a big deal in the transition phase, yet it's dangerous.

I think this deserves some thinking...