ユーザーデータRowにマスタデータRowへのアクセサを生やすこと

単なる反省&メモです。

反省

  • DBIx::SkinnyなどのO/R Mapper使ってる場合のお話です。
  • よくあるユーザーが所持しているアイテム一覧を表示するページで、便利だからついユーザーアイテムのRowにアイテムマスタのRowへのアクセサを生やして、それを意識せずループの中などで使ってしまうことがあります。。すみません。。
while ( my $user_item = $iter->next ) {
    print $user_item->item->name . "を" . $user_item->count . "個\n";
}
  • 特にテンプレートの中なんかでやってしまってさらにごめんなさいという感じです。

どうしよう

  • じゃあどうしようという話ですが、ユーザーアイテムデータから持っているアイテムidを取り出してアイテムテーブルにinで投げて、idをキーとしたハッシュに入れるっていうのがSQLの実行回数も少なくて、後でも使いやすくていいのかなと思ったりしています。
my $item_ids = [];
while ( my $user_item = $iter->next ) {
    push @$item_ids, $user_item->item_id;
}
my $item_hash = { map { $_->id => $_ } $db->search('item', { id => $item_ids})->iter->all };
$iter->reset;
while ( my $user_item = $iter->next ) {
    print $item_hash->{$user_item->item_id}->name . "を" . $user_item->count . "個\n";
}
    • またこういう場合って、マスタデータを全部キャッシュに載せておくことが多いのかなとも思ったりするのですがどうなのでしょうか!?

Tengで遊んでみた

  • というわけで、上記のような場合のベンチマークなどを勉強も兼ねてTengで試したりしています。
  • また、上記のようにidをキーにしたハッシュにしたい場合、DBIのselectall_hashrefのようなメソッドがあると便利だなぁと思い、勉強がてらTengのプラグイン書いてみました。
    • search_hashrefというデフォルトではidがキー、rowが値になったハッシュを返してくれるだけの関数です。
    • 上記のようにmap使ったりして1行で書けるのですが、、、毎回書くのが面倒だなぁと思ったので。。
    • https://github.com/koba04/p5-teng-plugin-searchhashref
  • Tengは使うのも簡単だし、ソースもシンプルでとても勉強になるモジュールですね!