読者です 読者をやめる 読者になる 読者になる

ITの隊長のブログ

ITの隊長のブログです。いや、まだ隊長と呼べるほどには至っていないけど、日々がんばります。CakePHPとPlayFrameworkを使って仕事しています。最近はAngular2をさわりはじめたお(^ω^ = ^ω^)

CakePHPで複合でユニークなバリデーションを実行

CakePHP

スポンサードリンク

http://www.flickr.com/photos/51052239@N00/3554882004
photo by iogi


さっぱりやったことが無いので、色々探してまずはBehaviorを作ってみた。


  • ~/app/Model/Behavior/UtillBehavior.php
<?php

/**
* モデル間での共通クラス
*/
class UtillBehavior extends ModelBehavior {
  /**
  * 複数キーをチェックする
  */ 
  public function checkUnique($data, $fields) {
    if (!is_array($fields)) {
      $fields = array($fields);
    }
    foreach($fields as $key) {
      $tmp[$key] = $this->data[$this->name][$key];
    }
    return $this->isUnique($tmp, false);
  }
}


んで、Modelに記述

  • ~/app/Model/Behavior/TestTestModel.php
<?php

class TestTestModel extends AppModel {
  // 使用したいビヘイビアを指定
  public $actsAs = array('Utill');

  // バリデーション
  public $validate = array(
    'id' => array(
      'custom' => array(
      'rule' => array('custom', '/^[0-9]{4}$/'),
      'message' => '対象年月はyyyy(2000)で入力してください',
      'allowEmpty' => true
    ),
    'unique' => array(
       // 独自で作成したメソッドで、ユニークチェックしたいフィールドを指定
       'rule' => array('checkUnique', array('id', 'value')),
       'message' => '同じ年が存在するので、登録できません'
     )
    )
  );
}


これでいいんじゃないかな?


が、致命的なエラー!


orz


どうやら、checkUnique()の $this->isUnique($tmp, false); がダメっぽい


しかも、自作クラス作成しなくともいけるって話を耳に。


結局は、バリデーションの記述だけでいけました。

<?php

class TestTestModel extends AppModel {
	// バリデーション
	public $validate = array(
		'target_year_month' => array(
			'custom' => array(
			'rule' => array('custom', '/^[0-9]{4}[\-]{1}[0-9]{2}+$/'),
			'message' => '対象年月はyyyy-mm(2000-09)で入力してください',
			'allowEmpty' => true
		),
		'unique' => array(
			// 独自で作成しなくとも、通常のバリデートメソッドでチェック
			'rule' => array('isUnique', array('target_year_month', 'monthly_cost_other_id'), false),
			'message' => '同じ年が存在するので、登録できません'
			)
		)
	);
}