読者です 読者をやめる 読者になる 読者になる

Re: DBIx::Skinny で update_or_create

http://d.hatena.ne.jp/magicalhat/20100121/1264076085より

オマケとして、UPDATE じゃなくて INSERT した場合には、関連するレコードも更新しなくちゃ!

とゆーパターンも想定して、DBIx::Class でも利用できる in_storage というメソッドもつけてみました。

のin_storageなのですが、現時点のHEADだと、Proj::Model->newされた前提でin_storageが実装されていて、上記の例は動きません。

ちょっとややこしいのですが、DBIx::Skinnyはnewしてもnewしなくてもsearchなどが使えて、newせずに使った場合わりとグローバルに作用するので、Skinny側へ副作用をもたらすようなメソッドはMixinではなるべく避けた方が無難だと思います。

またMixinは各モジュールが複数メソッドを提供していたりすると、色々使うようにしたときに、このメソッドはどれから生えてるのかわからないという状況になりがちなので、Mixinの名前のメソッドをそのまま生やして、極力1つのメソッドに留めるくらいが再利用性を高める上では良いんじゃないんかなと思っています。(ただこの例の場合は、Skinnyではfind_or_insertがfind_or_createの別名として許されているのでupdate_or_insertも許すというのはよいかもしれません。)

この場合、in_storageかどうかの判断は、update_or_createしたscopeでしか利用しないはずなので、wantarrayで、リストを受けようとしたときだけ、何をしたかが第二引数になるようなインターフェースならどうでしょうってことで実装してみました。(createしたときが特別扱いされるべきなのかは自分が必要になったケースがあまりないのでよくわからないです。よくわからないので文字列を返すようにしました)

http://github.com/walf443/p5-dbix-skinny-update_or_create/tree/dont_use_hashref


個人的にはDBICのupdate_or_createは使ったことはあまりなくて、find_or_createして、updateで十分かなといった感じです。 (Not nullとかの都合でできないこともあるかもですが)
createされたときに関連したテーブルのレコードを更新する場合は、アプリケーションのどういう部分かにもよりますが、Skinnyのpost_insert triggerを使うとよいことが多いんじゃないかなと思います。