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