今日のハマリ

DBIC 使っていたんですがなかなか使いこなせないですね。

PK::Auto で失敗

my $rec = $schema->resultset('t_test')->search(...)->first;
# うーむ,やっぱり新規で INSERT しよう
$rec->store_column('id', undef);  # PrimaryKey を undef に
$rec->insert;  # died!

みたいなことをやってだめでした(NULL constraint どうのこうの)。undef を set するとフィールド値をセットしないかな,と思ったんですが,そうすると単に NULL をいれようとするだけっぽいです。
あこぎながら

delete $rec->{_column_data}{id};

ということをやって応急処置。もちろんこういうことを常用してはいけないと思います。

$schema->resultset('t_test')->create(
  {
    'other_field1' => $rec->other_field1,
    ...
  }
);

とか。格好悪。

凝った UPDATE で失敗

$schema->resultset('t_test')->update(
  {
    field1 => 'field1 + 1',
  }
);

は,駄目でした(Integer field にいれられないよ)。まぁそれはそうだろ,という感じですが,なんとか直で SQL 書けないですかね。

JOIN で凝った条件を書いて失敗

実際には JOIN したというより,リレーション貼ってて prefetch で自動的に JOIN されたんですが,

$schema->resultset('t_parent')->search(
  {
    available => 1,
  },
  {
    order_by => 'id',
    prefetch => 't_child',
  }
);

みたいにすると,ambiguous identifier 'id' みたく怒られました。
SQL 文を吐くようにしてデバッグするとわかるんですが,こういう場合,主テーブルのテーブルには 'me' というエイリアスが指定されるので,

    order_by => 'me.id', 

とすればよいです。リレーション先のテーブルについては,リレーションの名前がつきます。どういうことかというと,

CD->belongs_to('artist' => 'Artist', 'artist_id');

$schema->resultset('CD')->search(
  {
    'artist.name' => { 'LIKE', 'M%' },
  },
  {
    prefetch => 'artist',
  },
);

みたいにすればよいということです。この Artist のテーブル名が t_artist だったとしても,上記でリレーションを「artist」という名前にしているので artist というエイリアスが貼られますから,「artist.ほにゃらら」でアクセスできます。