【问题标题】:DBIx::Class and overloading accessorsDBIx::Class 和重载访问器
【发布时间】:2019-04-08 21:59:53
【问题描述】:

(类似于#11526999,但有更具体的细节)

我的结果类是使用dbicdump 构建的,但是我希望重载date 字段的默认访问器。

有效,但有问题

为了hackytest我的想法,我只是在add_columns 调用的创建的date 键中添加了一个accessor 属性:

__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' },
);

...并在 Schema::Loader 校验和行下方创建了我的访问器例程:

# 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;
}

这可行,因为它返回预期的2014-10-04,但它是一个错误。

以正确的方式做事

问题是我已经破解了校验和代码,所以我不能巧妙地重新生成我的 Class 对象。

阅读ResultSourceCookBook 正确的方法似乎是:

dbicdump 构建的 ResultSource 作为标准:

__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 },
);

....添加一个更改访问器 行下,使用+ 表示它是对现有定义的更改:

# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:nB5koMYAhBwz4ET77Q8qlA

__PACKAGE__->add_columns(
  "+date", { accessor => '_date' },
);

....像以前一样使用重载方法

不工作。

我已经仔细检查了我的拼写,我尝试了add_column 而不是add_columns,并且我尝试将第二个add_columns 放在第一个的正下方 - 现在全部可用....代码使用默认访问器,并返回2014-10-04T00:00:00

如何覆盖默认访问器,以便使用自己的方法?

谢谢...

【问题讨论】:

    标签: perl dbix-class


    【解决方案1】:

    您需要的是作为加载程序选项传入的col_accessor_map

    col_accessor_map => {
      table_name => {
        date => _date,
      }
    }
    

    您可以使用-o 将加载程序选项传递给dbicdump

    $ dbicdump -o col_accessor_map="{ table_name => { date => _date } }" ... other options ...
    

    (将上面的 table_name 替换为您的表格名称 - 这很明显,对吧?)

    更新:这是未经测试发布的,当我终于开始测试它时,我发现它不起作用。在 IRC 上与the author 交谈后,我被告知col_accessor_map 选项不支持这种嵌套散列方法,因此如果您想使用这种方法,则需要使用 coderef。

    但是,作者也同意添加此支持将是一个好主意,我刚吃完午饭回来发现添加了该功能的 Github commit。不过我不知道它多久会到达 CPAN。

    这可能是第一次更新 CPAN 以使 SO 答案正确 :-)

    【讨论】:

    • 我使用的方法有问题吗?文档似乎暗示这是正确的道路......
    • 我在文档中看不到任何暗示您的 add_columns("+date" ...) 语法可以工作的内容。
    • metacpan.org/pod/… 描述了使用访问器重载和metacpan.org/pod/DBIx::Class::ResultSource#add_columns 的第三段引用('+col1') - 我将两者加在一起,并假设我可以将该语法附加到 ResultSource 包
    • 你是对的。让我看看,看看我能不能找出问题所在。
    • DBIx::Class::Schema::Loader 升级到0.07044(或更高版本)以获得col_accessor_map 功能。然后将-o col_accessor_map="{ table_name => { date => '_date' } }" 添加到命令行(并注意_date 周围的引号 - 必不可少!)
    【解决方案2】:

    我相信您可以在不同的抽象级别上使用方法修饰符

    use Class::Method::Modifier; # or Moose/Moo
    around date => sub {...};
    

    【讨论】:

      猜你喜欢
      • 2012-07-16
      • 2012-07-06
      • 1970-01-01
      • 2013-03-08
      • 2011-07-09
      • 1970-01-01
      • 2016-08-25
      • 2013-01-20
      • 2013-01-21
      相关资源
      最近更新 更多