DBIx::Class and overloading accessors

老子叫甜甜 提交于 2021-02-11 10:46:57

问题


(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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!