[CDBI] after_set_$col and after_create

Michael Peters mpeters at plusthree.com
Tue Oct 25 13:10:39 BST 2005

Kate Yoak wrote:
> I keep running into this inconsistency in using triggers and was wondering
> if there is a standard way to get around it.
> The statemtnt
> my $foo=Foo->create({first=>"hello", second=>"world"});
> is basically equivalent to
> my $foo = Foo->create();
> $foo->set(first=>"hello", second=>"world");
> $foo->update();

The key there is 'basically'. Inserting and updating are 2 different
things. If they are different, then there needs to be a way for the
programmer to do something different for each.

This mimics what most databases with real triggers do.

> with the exception of some performance considerations.  In general, we
> chosse one form over the other depending on the desired flow of execution,
> efficiency, etc.

That's not really true. We choose create()/INSERT when we have a new
record, and update()/UPDATE when we have an exising record.

> Foo->add_trigger(after_set_first => sub {shift()->flag(1) });
> This trigger will only be executed in the second example above - when we are
> using set() to place the values into the record, rather than create -
> Class::DBI::create() does not use set, nor calls after_set_ triggers.
> To fix this, we may add a before_create trigger that checks if we are
> setting the column and calls the same function.
> Now everything works as it should.  However, the default behavior seems off
> as the developer has to make sure all the after_set (or before_set) triggers
> are duplicated elsewhere.

If the duplication really bothers you, you can do something like:

sub _flag_this { shift()->flag(1) };
Foo->add_trigger(before_set_first => \&_flag_this);
Foo->add_trigger(before_create_first => \&_flag_this);

Michael Peters
Plus Three, LP

More information about the ClassDBI mailing list