DBIx::Class::Stash
ってのをつくってみました。
ちょっと微妙な実装だったり、ほかにいい方法あるんかもしれないですが
これくらいしか思いつかなかったので。
利用方法としてはたとえば
userテーブルにレコードを作成するときに
リレーションのあるプロフィールテーブルにもレコードを「絶対に」一緒に作るぜ!
ってな場合、こんな風にかいてもいいのですが、
my $user = $self->model('User')->create({ name => 'nekokak' }); $user->create_related('profile',{ zip1 => $zip1 });
みたいな感じでかいてもいいのですが、
別でUserテーブルにInsertをかける場合が発生したらこのプロフィールテーブルに
レコードをつっこむことをわすれてしまうことがあるかと思います。
なのでDBICでinsert時にHookしてみました。
(Loader使ってる前提)
package Proj::Schema::User; use strict; use warnings; __PACKAGE__->load_components(qw/ +Proj::Schema::User::_hooks /); 1; package Proj::Schema::User::_hooks use strict; use warnings; use base 'DBIx::Class'; sub insert { my $self = shift; # 先にinsertしておく my $user = $self->next::method(@_); $user->create_related('profile',{ zip1 => $zip1 }); return $user; } 1;
とかいうモジュールにフックを仕込んでおきたかったりしませんか?
でも、$zip1のデータはどうわたすのかとかちょっと悩ましいですよね。
そこで作ったのがDBIx::Class::Stashだったりします。
これを使えばこんな風にかけます
my $user_rs = $self->model('User') $user_rs->stash->{zip1} = $zip1; $user_rs->create({ name => 'nekokak' });
Hook側は
package Proj::Schema::User; use strict; use warnings; __PACKAGE__->load_components(qw/ +Proj::Schema::User::_hooks /); 1; package Proj::Schema::User::_hooks use strict; use warnings; use base 'DBIx::Class'; sub insert { my $self = shift; # 先にinsertしておく my $user = $self->next::method(@_); # ここがみそ $user->create_related('profile',{ zip1 => $self->stash->{zip1} }); return $user; } 1;
見たいな感じでかけます。
$user_rs->stash->{zip1} = $zip1;
をかかなければ一緒やんけーとかもありますが、
まぁいいじゃないですか。
Hook側でチェックするようにしてもいいですし。
どうでしょうかねぇ。
ソースはこちらからどうぞ。
http://code.mfac.jp/trac/file/CPAN/nekokak/DBIx-Class-Stash/lib/DBIx/Class/Stash.pm