CakePHPで指定したフォームにデータが存在する場合だけ、あるフォームのバリデーションを行うためのビヘイビアを書いてみた

CakePHPでフォームのバリデーションを行う場合、例えばチェックボックスで「選択肢A」が選択されている場合のみ、「アンケート」のテキストエリアを必須入力にしたい!といった事があるかと思います。

バリデーションルールを切り替えるというのも1つの手段かと思いますが、もっと簡単に、バリデーションの定義だけでそれを実現できる関数を、ビヘイビアとして書いてみたので公開します。

ソースコード

下記のassoc_field_validation.phpをダウンロードして、APP/models/behaviors/以下に設置してください。

使い方

ビヘイビアに含まれるcheckAssocField関数を、バリデーションのルール(ユーザー定義関数)として指定します。

下記のコードは、先ほどの「選択肢A」が選ばれていた場合に「アンケート」の入力を必須入力にする、というサンプルです。

class Contact extends AppModel
{
	public $validate = array(
		'option' => array(
			'inList' => array(
				'rule' => array('inList', array('A', 'B', 'C')),
				'required' => true,
				'allowEmpty' => false,
			)
		),
		'questionnaire' => array(
			'checkAssocField' => array(
				'rule' => array('checkAssocField', 'option', array('A'), 'notEmpty'),
				'message' => '必ず入力してください。',
				'required' => true,
			),
		),
	);
}

checkAssocField関数は3つの引数を取ります。

assocField (string)
値をチェックする入力フォーム名です。
assocValueList (array)
assocFieldで指定してた入力フォームの値がここで指定された値ならば、delegateRuleを用いてバリデーションを行います。
delegateRule (mixed)
assocFieldで指定したフォームの値がassocValueListの値に含まれる場合に、実行するバリデーションのルールを指定します。
ここでは他のバリデーションのルールを自由に指定する事が出来ます。
例)array('maxLength', 30)array('between', 20, 30)

注意

checkAssocField関数をバリデーションに利用した場合、そのフィールドのallowEmptyrequiredの指定に気をつけて下さい。

例えば上述の例の場合、allowEmptytrueと指定してしまうと、この関数は意味を成しません。(値が空でもOKということになるため、「選択肢」がAだとしても「アンケート」の値が空で通ってしまう)

また、allowEmptyfalseと指定すると、「選択肢」がAであれBであれ、「アンケート」が空の場合はエラーになってしまうため、これもまた意味がありません。

そこで、requiredのみをtrueとすることで値が空の状態でもバリデーションルールは実行する、という状態にする事が出来ます。

必須のチェックがしたければ、delegateRulenotEmptyを指定する事で行う事ができるので、allowEmptyではなくそちらを利用するようにしてください。

この指定にだけは気をつけて下さい。