Category: Catalyst Keywords: DBIx::Class inflate
DBIx::Class is great, 所以我在最近写的论坛代码 Foorum 中就使用了 DBIx::Class 作为我的 Model. (use base 'Catalyst::Model::DBIC';)但我挺喜欢 Class::DBI 的 Trigger,而 DBIx::Class 要使用这个东西似乎比较麻烦。按它 wiki 上的说法似乎要载入 use base qw/ DBIx::Class::CDBICompat::Triggers DBIx::Class::Core/; 没有其他的办法。我在写 Foorum 的注册程序,表 user 里有一个字段是 register_date 类型为 DATETIME。如果用 Trigger 的话似乎简单一些, register_date = NOW() 就可以(用 mysql 的函数)。还好 DBIx::Class 也提供了 inflate. 所以我就用这个来完成我的任务。 inflate 在这里只是一个暗喻,它主要用于在表的某一字段的数据存入或取出之前做一些变动。 deflate 用于做存入前的变动,而 inflate 做取出后的变动。在无法用 register_date = NOW() 之后,要将 localtime 或 gmtime 转为 DATATIME 类型似乎比较麻烦。还好 CPAN 上有一模块为 DateTime::Format::MySQL 用于将 DateTime 对象转为 MySQL 所需要的类型。所以代码很简单:
package Foorum::Model::DBIC::User;use strict;而当我们存入数据时就可以使用:
use base 'Foorum::Model::DBIC';use DateTime::Format::MySQL;__PACKAGE__->inflate_column( 'register_date',
{ inflate => sub { return shift; },
deflate => sub { DateTime::Format::MySQL->format_datetime( shift ); } }
);
use DateTime;当 create 创建新的 record 时,将传入的 register_date(这里是 DateTime->now;)先用 deflate 做一些变动,这里将它(shift 指的是 DateTime->now)处理(format_datetime)后再存入。
$c->model('DBIC')->table('user')->create({
username => $username,
password => $computed,
email => $email,
register_date => DateTime->now,
register_ip => $c->req->address,
});
而 inflate 反一下,指取出后立即处理的匿名函数。我这里只是直接返回,因为我不需要再处理。如果你想它取出来也是一个 DateTime 对象好方便你进一步处理的话,可以将 inflate 的函数改为:
inflate => sub { DateTime::Format::MySQL->parse_datetime( shift ); },:) have fun. 如有疑问,发 mail 跟我探讨。 thanks.