CakePHPのモデルには、DBを更新する際に値をチェックするvalidate機能があります。
今回、それを活用しようとプログラミングしてみたのですが、なかなか問題が多かったので、とりあえずメモとして残しておきます。
CakePHPのバージョンは1.3.6です。
プライマリキーの重複チェックを試す
Sampleモデルについて、validate機能でプライマリキーの重複チェックをする場合には、以下のようにモデルに記述するだけです。CakePHPはこの簡易さがありがたい。
class Sample extends AppModel { var $name = 'Sample'; var $validate = array( 'id' => array( array( 'rule' => 'isUnique', 'message' => '「ID」が重複しています', ), ), );
マニュアルにもあるように、この記述で問題ないはずですが、なぜかチェックは機能せず、エラーパターンでもスルーして正常処理を続行してしまいます。
原因は不明ですが、どうしても出来ないので、ひとまずこの方法はあきらめます。
独自で重複チェックの関数を用意する
組み込みのバリデーションルール以外に、独自でルールを構築する事もできるので、その方法で実装してみました。
class Sample extends AppModel { var $name = 'Sample'; var $validate = array( 'id' => array( array( 'rule' => array('myIsUnique'), 'message' => '「ID」が重複しています', ), ), );
「myIsUnique」が独自で用意するチェック関数です。同一クラス内に用意します。
function myIsUnique($check){ $results = $this->find('all', array( 'conditions' => array( 'Sample.id' => $check['id'], ), )); if(sizeof($results) == 0){ return true; }else{ return false; } }
「$check[‘id’]」は実際にチェックする値を参照しています。ここでの判定結果を「return false;」とすると、エラー処理が行われます。
とりあえず、重複エラーチェックを実装したいという目的は、これで実装できそうです。
更新処理ができなくなった
ここで、CakePHPでは特にINSERTとUPDATEを意識せずに構築できるしくみです。データの更新の際には、キーが存在しない場合はINSERT、一方、存在しない場合はUPDATEが実行されます。
つまり、INSERTの際のキー重複チェックは実現できたのですが、このままでは、更新の際にも重複チェックがかかってしまいます。このままではUPDATEが実行できません。
もちろんこのような場面のために、CakePHPでは「UPDATEの時だけチェックを外す」というような設定が可能です。
class Sample extends AppModel { var $name = 'Sample'; var $validate = array( 'id' => array( array( 'rule' => array('myIsUnique'), 'on' => 'create', 'message' => '「ID」が重複しています', ), ), );
逆に、属性「on」に「update」をセットするとUPDATEのみチェックされます。
しかし、さらなる問題が、、、
「on」を設定した後、なぜか関数「myIsUnique」で「$check」にアクセスできなくなってしまいました。どうやら独自関数を設定した場合、「on」は使えないようです。これではチェック機能自体が死んでしまい、ふりだしに戻ってしまった感じです。
とりあえず「on」を外し、「myIsUnique」の中でINSERTとUPDATEを振り分けできないかと奮闘してみましたが、今のところ解決には至っていません。
CakePHPをアップデートしたら直ってくれないかな
この一連の流れが、CakePHPとして正しい仕様なのか、不具合なのかは不明ですが、とりあえず、期待の意を込めてCakePHPを1.3.6から、現時点での最新版である1.3.9にアップデートしてみました。
しかし、何も改善せず。
結局、キー重複チェックはvalidateから外し、別途、実装するしかないそうです。
もう少し勉強してみます。
1.3.11 で isUnique がひとまず機能することは確認できました。
簡単ですがご報告まで。
ご報告ありがとうございます!
改善されてるんですね。よかった。
次にシステムを組む時に試したいと思います。