Software Engineer and Web Developer's Diary

1年後の自分に向けて

モデルの役割と使い方

モデルの役割は大きく分けて 3 つある。

  1. モデルとデータベースとの関連を定義する
  2. バリデーション
  3. 表示処理に必要な独自関数の定義

まず、
1. モデルとデータベースとの関連を定義する
について

CakePHPの何か の「CakePHPのModelを使う」発表資料PDF がわかりやすい

一応順に説明すると

var $name = 'User';

この記述の意味は、モデル名が 'User' ということと、このモデルに対応するテーブル名が 'users' であることを示す。わざわざ書かなくてもクラス名が User ならデフォルトで 'User' 設定される。

var $useTable = 'user_table';

モデルに対応するテーブル名を $name の設定から推測される名前以外を利用したい場合は、この変数で指定する。コントローラから findAll などの関数でアクセスするテーブルはこの変数で指定したものになる。

var $primaryKey = 'user_id';

モデルに対応するテーブルの主キーを設定します。設定しない場合は、主キーはデフォルトで 'id' と判断されるので、主キーが 'id' 以外の場合は設定してください。

主に上記 3 つの変数を使うことになると思います。

それ以外の関数については 6.3. モデルの変数 を参照してください。$transactional は更新系の処理では必要になると思います。

次に
2.バリデーション
について

CakePHPのModelを使う」発表資料PDF の P.33-37 と 12章 データバリデーション を読む。

簡単に言うと、$validate 変数に配列を設定し、save() か validates() メソッドを実行すると validation が実行される。

ただ、デフォルトの validation では空チェック、数値チェック、E-MAIL チェックぐらいしかないので、カスタマイズする必要がでてくる。

libs/validators.php への定義値の追加とか PDF の P.33 に書かれているように validates をオーバーライドするとか。
調べると hetimaの日記 - CakePHP 1.1系に1.2系のバリデーションを組み込む がよくまとまってるので同じように組み込んでみる。

app_model.php を app フォルダ直下にコピーし、hetima さんのロジックを組み込む。すると以下のエラーが発生する。

(Model::invalidFields) Parameter usage is deprecated,
set the $data property instead


原因は validates() の使い方が 1.2.x から変わっていて、今まで、validates($data) というように引数に $data を渡せていたものが渡せなくなっている。だから以下のようにまず set() してから validates() を呼ぶように書き方を変える。

$data['Top'] = array(
                      'login_id' => '++++',
                      'password' => 'abcde',
                      'name' => ''
                      );
$this->Top->set($data);
if ($this->Top->validates()) {
}


validateErrors() という関数を実行すると同じエラーが発生したのでこちらも変える。

cake/libs/controller/controller.php の validateErrors メソッドを変更する。

    function validateErrors() {
        $objects = func_get_args();
        if (!count($objects)) {
            return false;
        }

        $errors = array();
        foreach($objects as $object) {
            $this->{$object->name}->set($object->data);
            $errors = array_merge($errors, $this->{$object->name}->invalidFields());
        }
        return $this->validationErrors = (count($errors) ? $errors : false);
    }


validation の詳しい使い方は CakePHP のおいしい食べ方: CakePHP View を参照する。よく読まないと理解できないが、しっかり読めばなんとなくわかってくる。

1.2.x の validation の種類は cakebaker » Validation with CakePHP 1.2 を参照。(下記のような感じになる)

var $validate = array('username' => array('rule' => array('alphaNumeric')));


blank を試してみるとなぜかうまく動かない。

#2157 (Validate::blank return incorrect boolean) というチケットを見つけたのでバグかと思うとそんなこともないらしい。
よく cakebaker » Validation with CakePHP 1.2 を読むと 'blank' は空(から)という意味ではないよう。必須チェックは 1.1.x と同じ、VALID_NOT_EMPT でチェックすること。

最後に
3.表示処理に必要な独自関数の定義
について

PHP/CakePHP/CakePHPのモデルをエンティティとして扱う - Happy Engineer Life でやってる税込価格を表示する方法を考える必要がある。まったく真似するのもあり。

CakeShop/イテレーション/2-A2 商品を注文する - Happy Engineer Life のメッセージの共通化もやっておきたい。