问题
(Similar to, but with more concrete details that, #11526999)
My Result Classes have been built using dbicdump
, however I wish to overload the default accessor for a date
field.
Works, but a bodge
To hackytest my idea, I simply added an accessor
attribute to the created date
key of the add_columns
call:
__PACKAGE__->add_columns(
"stamp_id",
{
data_type => "integer",
is_auto_increment => 1,
is_nullable => 0,
sequence => "timestamp_stamp_id_seq",
},
"date",
{ data_type => "date", is_nullable => 0, accessor => '_date' },
);
... and created my accessor routine below the Schema::Loader checksum line:
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:nB5koMYAhBwz4ET77Q8qlA
sub date {
my $self = shift;
warn "overloaded date\n"; # Added for debugging
my $date;
# The date needs to be just the date, not the time
if ( @_ ) {
$date = shift;
if ( $date =~ /^([\d\-]+)/ ) {
$date = $1
}
return $self->_date($date)
}
# Fetch the column value & remove the time part.
$date = $self->_date;
if ( $date =~ /^([\d\-]+)/ ) {
$date = $1
}
return $date;
}
This works, as it returns an expected 2014-10-04
, but is a bodge.
Do it the right way
The problem is that I've hacked the checksum'd code, so I can't neatly re-generate my Class objects.
Reading ResultSource and the CookBook the correct approach appears to be:
Have the ResultSource built by dbicdump
as standard:
__PACKAGE__->add_columns(
"stamp_id",
{
data_type => "integer",
is_auto_increment => 1,
is_nullable => 0,
sequence => "timestamp_stamp_id_seq",
},
"date",
{ data_type => "date", is_nullable => 0 },
);
.... add a change the accessor below the line, using the +
to indicate it's an alteration to an existing definition:
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:nB5koMYAhBwz4ET77Q8qlA
__PACKAGE__->add_columns(
"+date", { accessor => '_date' },
);
.... use the overload method as before
Not working.
I've double-checked my spelling, I've tried add_column
rather than add_columns
, and I've tried putting the second add_columns
to directly below the first - all to now avail.... the code uses the default accessor, and returns 2014-10-04T00:00:00
How do I over-ride the default accessor, so I can use my own method?
Thankee...
回答1:
What you need here is a col_accessor_map passed in as a loader option.
col_accessor_map => {
table_name => {
date => _date,
}
}
You can pass loader options to dbicdump with -o
.
$ dbicdump -o col_accessor_map="{ table_name => { date => _date } }" ... other options ...
(Replace table_name
above with the name of your table - that's obvious, right?)
Update: This was posted untested, and when I finally got round to testing it, I found it didn't work. After a conversation with the author on IRC I was told that the col_accessor_map
option doesn't support this nested hash approach, so if you wanted to use this approach you would need to use a coderef.
However, the author also agreed that adding this support would be a good idea and I've just got back from lunch to find this Github commit which adds the feature. I don't know how soon it will get to CPAN though.
This may be the first time that CPAN has been updated to make a SO answer correct :-)
回答2:
At a different level of abstraction I believe you could use a method modifier
use Class::Method::Modifier; # or Moose/Moo
around date => sub {...};
来源:https://stackoverflow.com/questions/33634610/dbixclass-and-overloading-accessors