Home > CakePHP | PHP > CakePHP テーブルのカラムサイズでvalidate

CakePHP テーブルのカラムサイズでvalidate

この記事の所要時間: 241

モデルで文字列の長さをvalidateする際にテーブルのカラムサイズを使う方法です。

CakePHPではモデルがテーブルのカラム情報を保持しているのですが、この情報にはカラム名やデータ型の他にカラムサイズ(varchar(N)等)も含まれています。

そこでモデルのvalidateでこの値を使えば最低限テーブルのカラムに収まるかどうかはチェックできます。

ここでは以下のようなテーブルでnameとemailの文字列長をチェックします。(DBはPostgreSQL)

create table users (
id        serial            primary key
,name   varchar(50)   not null 
,email   varchar(100)   not null 
);

1. AppModelにカラムサイズ取得、文字列長チェックメソッドを追加する

AppModelにカラムサイズ取得用メソッド(getColumnLength)と文字列長チェックメソッド(validatesLength)を記述します。

<?php
class AppModel extends Model {
  /**
   * Returns the column type of a column length in the model
   *
   * @param string $column The name of the model column
   * @return integer
   * @access public
   */
  function getColumnLength($column) {
    $columns = $this->loadInfo();
    $columns = $columns->value;
    $cols = array();

    foreach($columns as $col) {
      if ($col['name'] == $column) {
        return $col['length'];
      }
    }
    return null;
  }

  /**
   * valid value length
   *
   * @param array $data
   * @param string $fields
   * @access public
   */
  function validatesLength($data, $fields) {
    foreach ($fields as $v) {
      $len = $this->getColumnLength($v);
      if (!empty($data[$v]) && mb_strlen($data[$v]) > $len) {
        $this->invalidate($v . '_len_' . $len);
      }
    }
  }
}
?>

2. モデルで文字列長をチェックする

モデルで文字列長チェックを呼びます。単に$dataとvalidatesLengthメソッドにチェックするカラムを配列で渡すだけでokです。

validatesLength内部ではテーブルのカラムサイズで文字列長チェックを行い、エラーならinvalidateメソッドを呼びます。このinvalidateメソッドに与える値[カラム名 + ‘_len_’ + カラムサイズ]がポイントです。これをモデルの$validationErrorsに持たせておくことにより、ビューで正規の文字列長を含んだエラーメッセージを動的に出力することができます。

<?php
  function validates($data = array()) {
    if (!parent::validates($data)) {
      return false;
    }
    if (empty($data)) {
      $data = $this->data;
    }
    $data = $data['User'];

    // 文字列長チェック
    $list = array('name', 'email');
    $this->validatesLength($data, $list);
  }
?>

3. HtmlExtヘルパでエラーメッセージを出力

文字列長エラーメッセージを動的に出力するメソッド(tagLengthErrorMsg)をHtmlヘルパーを継承したHtmlExtに定義しておきます。

<?php
class HtmlExtHelper extends HtmlHelper {
  /**                        
   * lengthエラーメッセージ表示
   *                    
   * @param string $field
   * @param string $name
   * @return string
   */                         
  function tagLengthErrorMsg($field, $name) {
    if (empty($this->validationErrors)) {
      return null;
    }
                             
    $this->setFormTag($field);
    foreach ($this->validationErrors[$this->model] as $k => $v) {
      if (preg_match("/^" . $this->field . "_len_([0-9]+)$/", $k, $m)) {
        $message = sprintf("%sは%d文字以内で入力してください。", $name, $m[1]);
        return $this->tagErrorMsg($field . "_len_" . $m[1], $message);
      } 
    }
    return null;
  }
}
?>

4. ビューテンプレートでヘルパ呼び出し

最後にビューテンプレートで先程のtagLengthErrorMsgメソッドを呼び出します。これは引数としてカラム名とエラーメッセージ用項目名を与えます。

<!-- エラー時は「氏名は50文字以内で入力して下さい。」を表示 -->
<?php echo $htmlExt->tagLengthErrorMsg('User/name', '氏名'); ?>
<!-- エラー時は「メールアドレスは100文字以内で入力して下さい。」を表示 -->
<?php echo $htmlExt->tagLengthErrorMsg('User/email', 'メールアドレス'); ?>

ソース内に文字列長を書かなくて良い

この方法では文字列長をテーブル定義から取得するので、ソースに文字列長を書く必要がありません。もしテーブルのカラムサイズが変わってもソースはそのままで新しいカラムサイズに対応することができます。

(ちなみにtext型などカラムサイズが無いものについてはテーブル定義情報(モデルの$_tableInfo)に直接文字列長を入れるという方法もあります。)

ここでは1.1系で記述していますが、1.2系ではvalidateが柔軟な形になっているので2.のモデルでのチェックはもうちょっとスマートに書けそうです。

Pocket

follow us in feedly

トラックバック:0

このエントリーのトラックバックURL
http://www.1x1.jp/blog/2007/06/cakephp_validate_length.html/trackback
Listed below are links to weblogs that reference
CakePHP テーブルのカラムサイズでvalidate from Shin x blog

Home > CakePHP | PHP > CakePHP テーブルのカラムサイズでvalidate

検索
フィード
メタ情報

Return to page top