DBIx-Class-TemporalRelations
view release on metacpan or search on metacpan
lib/DBIx/Class/TemporalRelations.pm view on Meta::CPAN
'modified' => [
[ 'doodads', 'modified_dt' ],
[ 'doohickies_modified', 'modified_dt' ], ],
'purchased' => [ 'doohickies_purchased', 'purchased_dt' ],
);
# Later code:
use My::Schema;
...
# There can be only one!
my $person = $schema->resultset('Person')->find({ name => 'D Ruth Holloway'});
my @doodads_she_modified = $person->doodads_modified; # Doodad rows
my $first_doodad = $person->first_doodad_created; # Doodad row or undef
my @doohickies = $person->doohickies_modified; # Doohickey rows
=head1 DESCRIPTION
This module sets up some convenience methods describing temporal relationships between
data elements. A fairly-common construct would be to have a table of users, who are
creating things, and we want to see lists of the things that they created, in a time
order. In SQL, this might be:
SELECT id, serial_number, created_dt
FROM thing
WHERE creator = (SELECT id FROM user WHERE username = 'geekruthie')
ORDER BY created_dt;
And in conventional L<DBIx::Class> parlance:
$schema->resultset('User')->find({ username => 'geekruthie'} )->things
->search({},{ order_by => 'created_dt'});
Easy enough, but with this module, you can do some more things that would require a bit more yak-shaving:
my $user = $schema->resultset('User')->find({username => 'geekruthie'});
@things = $user->things_created;
@things = $user->things_created_before($ts);
@things = $user->things_created_after($ts);
These methods let you order things in reverse-date order:
@things = $user->most_recent_things_created;
@things = $user->most_recent_things_created_before($ts);
@things = $user->most_recent_things_created_after($ts);
...and let's pick a specific thing, shall we?
$thing = $user->first_thing_created;
$thing = $user->last_thing_created;
$thing = $user->first_thing_created_after($ts);
$thing = $user->last_thing_created_before($ts);
And if you could also B<modify> things, and stashed the last time the thing was modified, and by whom, in the
C<thing> table:
@thing = $user->things_modified;
$thing = $user->last_thing_modified;
(...but see L</BUGS AND LIMITATIONS> for an important limitation on this behavior!)
=head1 CONFIGURATION
In your Result class, once you've loaded this component, you have three ways to
add temporal relationships:
=head2 Direct injection into C<source_info>
__PACKAGE__->source_info(
{
temporal_relationships =>
{ 'contraptions' => [ { verb => 'purchased', temporal_column => 'purchase_dt' } ] }
}
);
The C<temporal_relationships> sub-hash of C<source_info> can be manually populated. It is a
hashref, defined thusly:
{ '<relationship accessor>' => [
{ verb => '<desired_verb>', # mandatory
temporal_column => '<column_name_to_use_for_ordering>', # mandatory
singular => '<singular_noun>', # optional
plural => '<plural_noun>' # optional
},
...],
...}
If you do not specify the C<singular> or C<plural> terms, they will be inflected from
the C<relationship_accessor>.
=head2 Single method call
__PACKAGE__->make_temporal_relationship(
'<desired_verb>', # mandatory
'<relationship_accessor>', # mandatory
'<column_name_to_use_for_ordering>', # mandatory
'<singular_noun>' # optional
'<plural_noun>' # optional
);
=head2 Multiple-relationship method call
__PACKAGE__->make_temporal_relationships(
'<desired_verb>' => [
[ '<relationship_accessor>', # mandatory
'<column_name_to_use_for_ordering>' # mandatory
'<singular_noun>' # optional
'<plural_noun>' # optional
], [...]
],
...
);
=head1 DEPENDENCIES
=over 4
=item L<DBIx::Class>
=item Optionally, L<DBIx::Class::Candy>
=item L<Lingua::EN::Inflexion>
=item L<Sub::Quote>
=back
=head1 BUGS AND LIMITATIONS
=over 4
=item Overwriteable fields
If you set a temporal relationship on a field that can be overwritten, for example C<modified_by>, realize
that the temporal relationship will disappear. This isn't a full activity log! For that, you probably want
something like L<DBIx::Class::AuditAny> or other similar journaling module.
=back
=head1 ACKNOWLEDGEMENTS
Thanks goes out to my employer, Clearbuilt, for letting me spend some work time on this module.
Blame goes to L<Jason Crome|https://metacpan.org/author/CROMEDOME> for encouraging me in this sort of madness.
=head1 AUTHOR
D Ruth Holloway <ruth@hiruthie.me>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2022 by D Ruth Holloway.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
( run in 2.440 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )