以前からブログに書こうかどうか迷っていたものです。
DBIx::Class::UTF8Columnsでできるんですが、カラムを指定するのが面倒。
MySchemaはDBIx::Class::Schema::Loaderで自動生成してることもあって、あんまりMySchema/*をいじりたくない。
というわけで、inflate/deflate(DBIx::Class::InflateColumn)でやってます。
もっと簡単な方法あるんじゃないかなあ、と思って改めてCPANを探してみたのですがしっくりくるものが見当たらず。
とりあえず晒しておきます。
package MyApp::Model::MyModel; use base qw(Catalyst::Model::DBIC::Schema); my $inflate_utf8 = sub { my $value = shift; if ( !utf8::is_utf8($value) ) { utf8::decode($value); } return $value; }; my $deflate_utf8 = sub { my $value = shift; if ( utf8::is_utf8($value) ) { utf8::encode($value); } return $value; }; sub new { my $class = shift; my $self = $class->next::method(@_); foreach my $schema ( keys %{ $self->schema->class_mappings } ) { foreach my $column ( $schema->columns ) { my $data_type = $schema->column_info($column)->{data_type}; if ($data_type eq 'TEXT' || $data_type eq 'CHAR' || $data_type eq 'VARCHAR' ) { $schema->inflate_column( $column, { inflate => $inflate_utf8, deflate => $deflate_utf8 } ); } } } return $self; }
ちなみに上記ソースには書いてないですが、data_typeがDATETIME/TIMESTAMP等のときはDateTime::Format::*してます。↓ここで書いてたやつです。
「data_typeがTIMESTAMPだったらinflate_column仕掛ける」ってのをやっていたのに、できなくなってしまったではないか。あれー?こんなクラスあったっけ…。
DBIx::Class::InflateColumn::DateTime - Auto-create DateTime objects from date and datetime columns. - metacpan.org
DBIx-Class-0.07000(1年以上前)からあるらしい…全然知らなかった!恥ずかし過ぎる(><)
data_typeを見る方法は、名前で識別(「_onで終わってたら」とか)するより確実かなーと思って割と気に入ってます。