【CakePHP】ネストされた値のバリデーションについて

みなさま、お疲れさまです。

今回は業務で「CakePHP3」を取り扱っているので、それについてを記事にしたいと思います。

バリデーションが個人的には苦手で、先日混乱したけど出来たら意外と単純だったと思った実装についてまとめます。

■やりたいこと

 ・「購入するもの」と「個数」を1つ以上必須で登録する

 ・「購入するもの」と「個数」についての登録数は上限はないが、

 どちらかが入力されていたらその行は必須で登録する

イメージとしては、上記のように行いたいと思っています。

ネストされて値が送られてきたときにどうバリデーションしたらいいのかわからなかったので、

ネストについてのバリデーションが今回の課題でした。

今回は、商品IDが実在するかどうかについて等、細かい部分のバリデーションは行わないこととしています。

■実装

// この状態で入力されたデータが来るとする
$data = [
  'product_values' => [
    'product_id' => '',
    'product_number' => ''
  ]
];

$validator = new Validator();

// フィールドが存在するかどうか
$validator->requirePresence('product_values', true, '入力してください');
// 空のフィールドを認めるかどうか
$validator->allowEmptyArray('product_values', '入力してください', false);

$productValidator = new Validator();

$productValidator
  ->requirePresence('product_id', true, '入力してください')
  ->allowEmptyArray('product_id', '入力してください', false)
  ->add('product_id', [
    // スカラーかどうか
    'isScalar' => [
      'rule' => ['isScalar'],
      'last' => true,
      'message' => '不正な値です'
    ],
  // 0以上の自然数か
    'nonNegativeInteger' => [
      'rule' => ['naturalNumber', true],
      'last' => true,
      'message' => '不正な値です'
    ]
  ]);

$productValidator
  ->requirePresence('product_number', true, '入力してください')
  ->allowEmptyArray('product_number', '入力してください', false)
  ->add('product_number', [
    'isScalar' => [
      'rule' => ['isScalar'],
      'last' => true,
      'message' => '不正な値です'
    ],
    'nonNegativeInteger' => [
      'rule' => ['naturalNumber', true],
      'last' => true,
      'message' => '不正な値です'
    ]
  ]);

$validator->addNestedMany('product_values', $productValidator);

ネストされたフィールドの値をバリデーションするには、「addNested()」または「addNestedMany()」を使用するとできるとのことでした。

cakePHPの公式サイトより、違いは下記のようになっています。

◎addNested()

 1:1の関係を構築することができる

◎addNestedMany()

 1:Nの関係を構築することができる

今回は、1:Nに該当したため「addNestedMany()」を使用しました。