DBIx-Class-Events

 view release on metacpan or  search on metacpan

lib/DBIx/Class/Events.pm  view on Meta::CPAN

        = $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 L</CONFIGURATION AND ENVIRONMENT> for how to set up the tables.

=head1 DESCRIPTION

A framework for capturing events that happen to a Result in a table,
L</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.

=over

=item when a user on a website clicks a particular button

=item when a recipe was prepared

=item when a song was played

=item anything that doesn't fit in the main table

=back

=head1 CONFIGURATION AND ENVIRONMENT

=head2 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 C<$event_type> is a string defining the "type" of event being created.
The C<%col_data> is a reference to the parameters passed in.

No default values, but if your database doesn't set a default for
C<triggered_on>, you may want to set it to a C<< DateTime->now >> object.

=head2 events_relationship

An class accessor that returns the relationship to get from your object
to the relationship.

Default is C<events>, but you can override it:

    __PACKAGE__->has_many(
        'cd_events' =>
            ( 'MyApp::Schema::Result::ArtistEvents', 'cdid' ),
        { cascade_delete => 0 },
    );

    __PACKAGE__->events_relationship('cd_events');

=head2 Tables

=head3 Tracked Table

The table with events to be tracked in the L</Tracking Table>.

It requires the Component and L</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 );
    }

=head3 Tracking Table

This table holds the events for the L</Tracked Table>.

The C<triggered_on> column must either provide a C<DEFAULT> value
or you should add a default to L</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 0.907 second using v1.01-cache-2.11-cpan-56fb94df46f )