マニュアルによると...
CakePHP には、データベースに値をセーブする際にその値を検証する「Validation」機能が備わっています。標準でも、必須チェックをはじめとする様々な検証ルールが提供されています。
その一つに、重複チェック(isUnique)があります。
マニュアルには、
public $validate = array( 'login' => array( 'rule' => 'isUnique', 'message' => 'そのユーザ名はすでに使われています。' ) );
や
public $validate = array( 'email' => array( 'rule' => array('isUnique', array('email', 'username'), false), 'message' => 'このユーザ名とメールアドレスの組み合わせはすでに使われています。' ) );
のように、入力された値がまだ登録されていないことを確認する方法のみが紹介されています。
しかし、別の条件を追加したい場合もあります。
条件を追加する
どのようにすれば条件を追加できるか検討してみましょう。
重複チェックは Model クラスで実装されているようなので、Model.php
を確認してみます。
/**
* Returns false if any fields passed match any (by default, all if $or = false) of their matching values.
*
* Can be used as a validation method. When used as a validation method, the `$or` parameter
* contains an array of fields to be validated.
*
* @param array $fields Field/value pairs to search (if no values specified, they are pulled from $this->data)
* @param bool|array $or If false, all fields specified must match in order for a false return value
* @return bool False if any records matching any fields are found
*/
public function isUnique($fields, $or = true) {
if (is_array($or)) {
$isRule = (
array_key_exists('rule', $or) &&
array_key_exists('required', $or) &&
array_key_exists('message', $or)
);
if (!$isRule) {
$args = func_get_args();
$fields = $args[1];
$or = isset($args[2]) ? $args[2] : true;
}
}
if (!is_array($fields)) {
$fields = func_get_args();
$fieldCount = count($fields) - 1;
if (is_bool($fields[$fieldCount])) {
$or = $fields[$fieldCount];
unset($fields[$fieldCount]);
}
}
foreach ($fields as $field => $value) {
if (is_numeric($field)) {
unset($fields[$field]);
$field = $value;
$value = null;
if (isset($this->data[$this->alias][$field])) {
$value = $this->data[$this->alias][$field];
}
}
if (strpos($field, '.') === false) {
unset($fields[$field]);
$fields[$this->alias . '.' . $field] = $value;
}
}
if ($or) {
$fields = array('or' => $fields);
}
if (!empty($this->id)) {
$fields[$this->alias . '.' . $this->primaryKey . ' !='] = $this->id;
}
return !$this->find('count', array('conditions' => $fields, 'recursive' => -1));
}
'conditions' => $fields
と条件を指定して、検索していることが分かります。
ならば、$fields
に検索条件を指定すればよさそうです。そこで該当のモデルの Validation rules を、
public $validate = array(
'column1' => array(
'isUnique' => array(
'rule' => array('isUnique', array('column1', 'column2 <>' => 'D'), FALSE),
),
),
);
のようにしてみました。
'column2 <>' => 'D'
が、追加したい条件です。
自カラム(column1
)を明示的に指定する必要がありますが、思ったように重複チェックができました。
ここで紹介する内容は、弊社で確認した一例です。
本ページを参考に作業をされ、何らかのトラブルや損失・損害等が発生しましても一切責任を負えません。自己責任でお願いします。