DBIx-Class-Events
view release on metacpan or search on metacpan
# After a few more name changes, split-ups, and getting back together,
# we find an event we should have considered, but didn't.
my $death_event
= $artist->event( death => { details => { who => 'drummer' } } );
# but, we then go back and modify it to note that it was only a rumor
$death_event->details->{only_a_rumour} = 1;
$death_event->make_column_dirty('details'); # changing the hashref doesn't
$death_event->update
# And after even more new names and arguments, they split up again
$artist->delete;
See "CONFIGURATION AND ENVIRONMENT" for how to set up the tables.
DESCRIPTION
A framework for capturing events that happen to a Result in a table,
"PRECONFIGURED EVENTS" are triggered automatically to track changes.
This is useful for both being able to see the history of things in the
database as well as logging when events happen that can be looked up
later.
Events can be used to track when things happen.
when a user on a website clicks a particular button
when a recipe was prepared
when a song was played
anything that doesn't fit in the main table
CONFIGURATION AND ENVIRONMENT
event_defaults
A method that returns an even-sized list of default values that will be
used when creating a new event.
my %defaults = $object->event_defaults( $event_type, \%col_data );
The $event_type is a string defining the "type" of event being created.
The %col_data is a reference to the parameters passed in.
No default values, but if your database doesn't set a default for
triggered_on, you may want to set it to a DateTime->now object.
events_relationship
An class accessor that returns the relationship to get from your object
to the relationship.
Default is events, but you can override it:
__PACKAGE__->has_many(
'cd_events' =>
( 'MyApp::Schema::Result::ArtistEvents', 'cdid' ),
{ cascade_delete => 0 },
);
__PACKAGE__->events_relationship('cd_events');
Tables
Tracked Table
The table with events to be tracked in the "Tracking Table".
It requires the Component and "events_relationship" in the Result
class:
package MyApp::Schema::Result::Artist;
use base qw( DBIx::Class::Core );
...;
__PACKAGE__->load_components( qw/ Events / );
# A different name can be used with the "events_relationship" attribute
__PACKAGE__->has_many(
'events' => ( 'MyApp::Schema::Result::ArtistEvent', 'artistid' ),
{ cascade_delete => 0 },
);
You can also add custom events to track when something happens. For
example, you can create a method to add events when an artist changes
their name:
__PACKAGE__->add_column(
last_name_change_id => { data_type => 'integer' } );
__PACKAGE__->has_one(
'last_name_change' => 'MyApp::Schema::Result::ArtistEvent',
{ 'foreign.artisteventid' => 'self.last_name_change_id' },
{ cascade_delete => 0 },
);
sub change_name {
my ( $self, $new_name ) = @_;
my $event = $self->event( name_change =>
{ details => { new => $new_name, old => $self->name } } );
$self->last_name_change( $event );
# $self->update; # be lazy and make our caller call ->update
$self->name( $new_name );
}
Tracking Table
This table holds the events for the "Tracked Table".
The triggered_on column must either provide a DEFAULT value or you
should add a default to "event_defaults".
package MyApp::Schema::Result::ArtistEvent;
use warnings;
use strict;
use JSON;
use base qw( DBIx::Class::Core );
__PACKAGE__->load_components(qw/ InflateColumn::DateTime /);
__PACKAGE__->table('artist_event');
__PACKAGE__->add_columns(
artisteventid => { data_type => 'integer', is_auto_increment => 1 },
artistid => { data_type => 'integer' },
# The type of event
event => { data_type => 'varchar' },
# Any other custom columns you want to store for each event.
triggered_on => {
data_type => 'datetime',
default_value => \'NOW()',
},
# Where we store freeform data about what happened
details => { data_type => 'longtext' },
);
__PACKAGE__->set_primary_key('artisteventid');
# You should set up automatic inflation/deflation of the details column
# as it is used this way by "state_at" and the insert/update/delete
# events. Does not have to be JSON, just be able to serialize a hashref.
{
my $json = JSON->new->utf8;
__PACKAGE__->inflate_column( 'details' => {
inflate => sub { $json->decode(shift) },
deflate => sub { $json->encode(shift) },
( run in 1.663 second using v1.01-cache-2.11-cpan-5837b0d9d2c )