Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Overriding method in multiple DBIx::Class child classes

by MattLG (Sexton)
on Sep 16, 2016 at 08:26 UTC ( [id://1171920]=perlquestion: print w/replies, xml ) Need Help??

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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1171920]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (6)
As of 2024-04-19 16:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found