MattLG has asked for the wisdom of the Perl Monks concerning the following question:

I have a series of DBIx::Class classes that have been auto-generated by the Schema Loader.

I also want to maintain an audit trail of changes to any database table entries, so I've started overriding the update() method on each. But after the first couple, I've realised that the overrides will actually be completely identical.

I'd obviously rather not duplicate 35 lines of identical code in all 20 classes if I can get away with it. What is the best way to achieve this?

--------------------- | DBIx::Class::Core | | update() | --------------------- / | | \ / | | \ ------------ ------------ ------------ ------------ | Table A | | Table B | | Table C | | Table D | ....... | update() | | update() | | update() | | update() | ------------ ------------ ------------ ------------

The first option that I considered was multiple inheritance, but the overriding method needs to call its parent method in the DBIx::Class::Core:

sub update { my __PACKAGE__ $self = shift; # Pre-processing : : : # Call the parent method $self->next::method(\%new_values); # If successful, record audit trail : : : }

Replies are listed 'Best First'.
Re: Overriding method in multiple DBIx::Class child classes
by Your Mother (Archbishop) on Sep 16, 2016 at 16:33 UTC

    This should be what you want. A couple of stubs and fake names shown to give you ideas for how to fill in the blanks. :P The new helper component–

    package MyDB::Audit; use parent qw( DBIx::Class ); use strict; use warnings; sub update { my $self = shift; return $self->next::method(@_) if some_reason_not_to_log_this_one($self->table); my %data = $self->get_dirty_columns; _log_changed_data(\%data); $self->next::method(@_); } 1;

    One of your current result source classes–

    package MyDB::Result::Dingus; use strict; use warnings; use parent "DBIx::Class::Core"; __PACKAGE__->load_components("+MyDB::Audit"); __PACKAGE__->table("Dingus"); __PACKAGE__->add_columns( ...et cetera... );

    Have fun. :P

      Hey, that worked! Thanks!

      Is that because the update() in MyDB::Audit isn't overriding a parent method in DBIx::Class, so it finds the next appropriate "parent" method?

Re: Overriding method in multiple DBIx::Class child classes
by talexb (Chancellor) on Sep 16, 2016 at 14:16 UTC

    Without thinking about this too much, can you just put the logging code in one place, then call it from each of the four methods?

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

      Yes, that would work. I'd rather do it in a cleaner OO way if possible though.

Re: Overriding method in multiple DBIx::Class child classes
by trwww (Priest) on Sep 21, 2016 at 19:52 UTC

    You're using dbicdump? You can use the additional_base_classes option and put your update method in the base class definition. Use

    -o additional_base_classes='["MyAppDB::ResultBase"]'

    as an argument to dbicdump.