順調に趣味のサイトをcakePHPにて開発しいたが、どうしてもsave関連のメソッドの挙動が気にくわない

save($data)

$data中にprimary_keyが存在すればupdate, 無ければinsert
で、insertの方には問題がないが、updateの場合は$data[id]がテーブル上に存在し無ければ、insertしてくれるというお節介を起こす。

update前に、SELECT COUNT(*) FROM MODEL WHERE ID=IDって問い合わせしている。
そもそもUPDATE後に、affected_rowsで調べるのでは、ダメなんだろうか?

例えば、find, read等で行を取得。
テーブルをLOCKした上で、取得したなら問題ないが、save等で保存するまでの間に、該当行が削除されてしまった場合、予想外にinsertされてしまう。

これは、saveFieldでも同じ。

確かにsaveという響きから想像できる挙動ではあるが、出来ればprimary keyがある場合で、idが存在しないならfalseを返してほしい。

save後に、Model->idへ該当IDが入るので、元のデータと比較すれば、updateされたのか?insertされたのかを検査する事は出来る
insertされた場合には、元のデータのidとは違うlastInsertIdになっている。

でも、面倒だからupdateAllを使うけどね


あと、戻り値

例えば、

if ( Model->save($data) ) {
 print 更新しました
}

もしくは
if ( !Model->save($data) ) {
print 失敗だよ
}

って書いてはいけない!!

なぜなら、$dataの配列が正確でなかった場合、insertもupdateもされずに、trueが返ってしまうのだ。

正確にinsert,もしくはupdateされた場合は、created等が補完された
[Model] => array( id => 1, created=> datetime, field => ・・・

的な配列が返る

なので、 is_arrayで検査しないといけない
falseが返るのは、sqlエラーが発生した時だけなので注意が必要だ。
saveでは、primary key以外の
unique違反でしか発生しないかな?


でも、save、saveFieldメソッド、便利な感じなんだけどね~

INSERTする以外は、使えそうにない。

saveAllは、また戻り値が複雑。
optionのatomic = true(デフォルト)の場合、成功すればtrue, 失敗は空の配列が返る。
しかし他でModel->begin()している場合には、atomic = falseとしてsaveAllを呼ぶが、その場合の戻り値は、array(Model => true, Model => false)といった感じになるのだ。
なので、atomic = falseとした場合は、戻りを検査しないといけない。

cakePHPの公式サイトは親切でそれなりに充実しているが、ほとんど戻り値に関してふれられていない気がするんだが。。
意外に情報がないのだけど、みんな、どうしてるんだろw。



関係ないグチ

プログラマーといっても、そのレベルはピンキリだ。
以前、メールアドレスを検証するコードで、

for ( $i = 0; $i < strlen($address); $i++ ) {
$moji = substr($address, $i, 1);
if ( $moji == '@' && $i == 0 ) {
return false;
} elseif ( $moji == 'a' ・・・・使える記号へ続く・・・

} else {
return false; //上のリスト以外の文字
}
ってコードを見た時は大爆笑したww
ってゆーか、変数名$mojiってなんだよwww$strとかあるじゃんw

もっとシンプルな方法があるはずだ!って思考出来ないのだ

この手のタイプは何事においても検証しないので、結果、穴だらけのプログラムが放置される。

でも、結構この手のタイプが、プログラマとして使い物にならないので、偉くなったりするwww

そして、優秀なプログラマーのモチベーションを奪うんだなぁーw