« Data::Pageとページナビゲーション | メイン | Data::Page::Navigation いい感じのページナビゲーション »

FormValidatorとDBIx::Class::WebFormの組み合わせはいい。

Scaffoldなどではすでに使われているのだけど、FormValidator::Simple(Data::FormValidator)とDBIx::Class::WebForm(Class::DBIの場合はClass::DBI::FromForm)、この組み合わせはヤバいね。非常に楽ができてしまう。

研究中のCatalystアプリの部分だけど、タイトルと、内容、時間(年〜秒まで6つのフォーム)があって、それをDBに入れる場合、

    my $result = $c->form(
        title=>[qw/NOT_BLANK/],
        text=>[qw/ANY/],
        {created_on=>[qw/d_year d_month d_day d_hour d_min d_sec/]}=>[qw/NOT_BLANK DATETIME/]
    );
    $c->detach('default') if $c->form->has_error;
    
    my $entry = MyApp::Model::DBIC::Entry->create_from_form($result);


これで確認も保存もできてしまう。 ちなみにテーブル定義は↓です。

create table entry(
    id int unsigned not null auto_increment,
    title varchar(250) not null,
    text text,
    created_on datetime not null
);


アップデートの場合は、

    my $entry = MyApp::Model::DBIC::Entry->find($c->req->params->{entry});
    $c->req->params->{id}=$c->stash->{entry}->id;#データベース上はIDなので
    my $result = $c->form(
        id=>[qw/ANY/],
        title=>[qw/NOT_BLANK/],
        text=>[qw/ANY/],
        {created_on=>[qw/d_year d_month d_day d_hour d_min d_sec/]}=>[qw/NOT_BLANK DATETIME/]
    );
    $c->detach('default') if $c->form->has_error;
    
    $entry->update_from_form($result);


こうやって書ける。

WebFormをLoaderと同時に使う場合(CatalystのヘルパーでModelクラスをつくった時など)のWebFormの追加の方法は、

__PACKAGE__->config(
    dsn           => '**',
    user          => '**',
    password      => '**',
    additional_base_classes   => 'DBIx::Class::WebForm',
    options       => {},
    relationships => 1
);


で行ける模様。
ValidatorとO/Rマッパーの連携のすばらしさを実感。

コメント

Catalyst::Plugin::FVS
のほうにはちょろっと書いておいたんですが、
そのへん本体のドキュメントに書くの忘れてましたね…
DATETIME型はちょっと特殊に扱えるようになってます。
$result->valid('created_on');
で返すデータはオプションで
datetime_class => 'DateTime' のようにして
DateTimeとかTime::Pieceのオブジェクトにもできます。
DateTimeの場合は
time_zone => 'Asia/Tokyo'
とかも。
なんにも指定しないと、
2005-11-25 00:00:00
みたいな形で返します。

Class::DBI::Plugin::DateTime
みたいなの使う場合にいいかも。

フォームにないデータを一緒に
*_from_form で突っ込みたい場合は、
$result->record('key')->data('hoge');
とかやって強制的に新しいキーとデータ作成できます。

なんでシングルキーでANY使ってるのかなーと
最初思ったんですけど
たぶん無理矢理キー作りたいってことですよね?

あとNOT_BLANKキーは複数キー用になってないです。
複数キー用に ALL とか作っておきますね。

全体的にDoc不足ですね。反省。

katoさん、いつもながら参考になります。

datetime_classはみてませんでしたが、inflate/deflateとあわせるといい感じですね。DBIx::Classのinflate/deflateは
DBIx::Class::InflateColumnのinflate_columnメソッドでinflateだけ試してます。

> なんでシングルキーでANY使ってるのかなーと
っていうのはまさにその通りで、
$result->record('key')->data('hoge');
も使えそうですが
key=>[qw/ANY/],
の方が直感的かなぁと思いました。

DBIx::Class::WebForm では?

うわぁぁぁ。素で気づかなかった。
tokuhirom様、ありがとうございます。

コメントを投稿