フォームのコレクションを埋め込む方法のシナリオを使用して、Task
常に少なくとも1つあることを確認したいと思いTag
ます。ただし、私の場合、との関係はTask
でTag
は1:n
なくですn:m
。
私は特にすべてTags
が削除されるシナリオに関心があります(これを防ぎたいです)。Task
フォームに常に少なくとも1つあることを確認するにはどうすればよいTag
ですか?
フォームのコレクションを埋め込む方法のシナリオを使用して、Task
常に少なくとも1つあることを確認したいと思いTag
ます。ただし、私の場合、との関係はTask
でTag
は1:n
なくですn:m
。
私は特にすべてTags
が削除されるシナリオに関心があります(これを防ぎたいです)。Task
フォームに常に少なくとも1つあることを確認するにはどうすればよいTag
ですか?
m0cで指摘されているように、解決策は実際にカスタム検証制約を利用することでした。しかし、そのような制約バリデーターがすでにSymfony2.1に存在することを知り、2.0に移植する自由を取りました(一部のインターフェースは2.1で明らかに変更されたため)。
Bernhard Schussekの 移植バージョン(2.0用)とCount.php
コレクションCountValidator.php
のカウント用です(https://github.com/symfony/Validator/tree/master/Constraintsを参照)。
namespace MyVendor\MyBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\MissingOptionsException;
/**
* @Annotation
*
* @api
*/
class Count extends Constraint
{
public $minMessage = 'This collection should contain {{ limit }} elements or more.';
public $maxMessage = 'This collection should contain {{ limit }} elements or less.';
public $exactMessage = 'This collection should contain exactly {{ limit }} elements.';
public $min;
public $max;
public function __construct($options = null)
{
if (null !== $options && !is_array($options)) {
$options = array(
'min' => $options,
'max' => $options,
);
}
parent::__construct($options);
if (null === $this->min && null === $this->max) {
throw new MissingOptionsException('Either option "min" or "max" must be given for constraint ' . __CLASS__, array('min', 'max'));
}
}
}
namespace MyVendor\MyBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
class CountValidator extends ConstraintValidator
{
/**
* {@inheritDoc}
*/
public function isValid($value, Constraint $constraint)
{
if (null === $value) {
return false;
}
if (!is_array($value) && !$value instanceof \Countable) {
throw new UnexpectedTypeException($value, 'array or \Countable');
}
$count = count($value);
if ($constraint->min == $constraint->max
&& $count != $constraint->min) {
$this->setMessage($constraint->exactMessage, array(
'{{ count }}' => $count,
'{{ limit }}' => $constraint->min,
));
return false;
}
if (null !== $constraint->max && $count > $constraint->max) {
$this->setMessage($constraint->maxMessage, array(
'{{ count }}' => $count,
'{{ limit }}' => $constraint->min,
));
return false;
}
if (null !== $constraint->min && $count < $constraint->min) {
$this->setMessage($constraint->minMessage, array(
'{{ count }}' => $count,
'{{ limit }}' => $constraint->min,
));
return false;
}
return true;
}
}
リレーションショップがエンティティレベルでマップされているプロパティにコレクション内の要素が含まれているかどうかを確認するカスタムバリデーターを作成します。
そしてバリデーターは失敗します:
public function isValid($value, Constraint $constraint)
{
if (count($value) <1 ) {
//also define a message for your custom validator
$this->setMessage($constraint->message, array('%string%' => $value));
return false;
}
return true;
}
このカスタムバリデーターを実装する方法については、http ://symfony.com/doc/current/cookbook/validation/custom_constraint.htmlをご覧ください。
投稿時に検証したいのですが、少なくとも1つのタグがあるかどうかは関係ありません。
または、ロード時にフォームに実際に1つの空のタグが含まれているようにしますか?( 「タスクフォームに常に少なくとも1つのタグがあることを確認するにはどうすればよいですか?」と言うので、私はそう思います)
あなたが2番目を必要とするならば、ちょうど
$tag1 = new Tag();
$tag1->name = 'tag1';
$task->getTags()->add($tag1);
前
$form = $this->createForm(new TaskType(), $task);
ドキュメントが言うように..