交响乐 3 | CollectionType 实体的自定义约束
Symfony 3 | Custom constraints on CollectionType entities
我按照文档进行操作,并能够在我的许多字段上添加自定义约束 (http://symfony.com/doc/current/validation/custom_constraint.html)。
我发现 CollectionType 字段有问题。
我的自定义约束只是检查用户是否没有在字段中点击多个 space(无论如何约束都不重要)。
我有一个带有标题和答案的问题表:
$builder
->add('title', TextType::class)
->add('answers', CollectionType::class, array(
'entry_type' => AnswerType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false
))
我有我的限制:
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class ContainsText extends Constraint
{
public $message = 'constraint_error';
}
我的约束验证器:
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class ContainsTextValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
// It checks if user didn't had multiple space in field
if (strlen(trim($value)) == 0) {
$this->context->buildViolation($constraint->message)
->addViolation();
}
}
}
在我的实体中:
问题:
use XX\XXBundle\Validator\Constraints as CustomAssert;
class Question
{
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=255, unique=true)
* @CustomAssert\ContainsText
*/
private $title;
...
}
答案:
use XX\XXBundle\Validator\Constraints as CustomAssert;
class Answer
{
/**
* @var string
*
* @ORM\Column(name="text", type="string", length=255, unique=true)
* @CustomAssert\ContainsText
*/
private $text;
...
}
在我的表单验证中,如果我在问题标题中点击了很多 space,我会收到表单验证错误以及 "constraint_error" 消息 => 一切正常。
但是,如果我在问题答案文本中点击许多 space,表单验证不会 return 任何错误,并且我的问题是用空答案创建的!
似乎,如果该字段来自 CollectionType,则自定义断言将被忽略。
我不明白的是,如果我在答案文本上有一个断言(如@Assert\Blank(),而不是自定义断言),即使我们在 CollectionType 中,断言也不是被忽略,我无法验证一个空白答案的表单。
我在这里错过了什么? TY
不确定您使用的是哪个 Symfony 2 版本,但取决于它是 pre 2.8 还是更高版本,您有不同的方法来解决这个问题:
v2.8+ 和 v3.0+
从 v2.8
开始,我怀疑您可能会使用 AnswerType::class
,cascade_validation
已弃用。相反,您需要对 Question::$answers
class 成员应用 Valid
约束。像这样:
class Question
{
/**
* ... Other anotaions go here
*
* @Assert\Valid()
*/
private $answers
}
v2.8 之前的版本:
您需要指定cascade_validation
选项:
$builder
->add('title', TextType::class)
->add('answers', CollectionType::class, array(
'entry_type' => AnswerType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'cascade_validation' => true // <========= THIS
));
希望这对您有所帮助...
我按照文档进行操作,并能够在我的许多字段上添加自定义约束 (http://symfony.com/doc/current/validation/custom_constraint.html)。
我发现 CollectionType 字段有问题。 我的自定义约束只是检查用户是否没有在字段中点击多个 space(无论如何约束都不重要)。
我有一个带有标题和答案的问题表:
$builder
->add('title', TextType::class)
->add('answers', CollectionType::class, array(
'entry_type' => AnswerType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false
))
我有我的限制:
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class ContainsText extends Constraint
{
public $message = 'constraint_error';
}
我的约束验证器:
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class ContainsTextValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
// It checks if user didn't had multiple space in field
if (strlen(trim($value)) == 0) {
$this->context->buildViolation($constraint->message)
->addViolation();
}
}
}
在我的实体中:
问题:
use XX\XXBundle\Validator\Constraints as CustomAssert;
class Question
{
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=255, unique=true)
* @CustomAssert\ContainsText
*/
private $title;
...
}
答案:
use XX\XXBundle\Validator\Constraints as CustomAssert;
class Answer
{
/**
* @var string
*
* @ORM\Column(name="text", type="string", length=255, unique=true)
* @CustomAssert\ContainsText
*/
private $text;
...
}
在我的表单验证中,如果我在问题标题中点击了很多 space,我会收到表单验证错误以及 "constraint_error" 消息 => 一切正常。
但是,如果我在问题答案文本中点击许多 space,表单验证不会 return 任何错误,并且我的问题是用空答案创建的!
似乎,如果该字段来自 CollectionType,则自定义断言将被忽略。
我不明白的是,如果我在答案文本上有一个断言(如@Assert\Blank(),而不是自定义断言),即使我们在 CollectionType 中,断言也不是被忽略,我无法验证一个空白答案的表单。
我在这里错过了什么? TY
不确定您使用的是哪个 Symfony 2 版本,但取决于它是 pre 2.8 还是更高版本,您有不同的方法来解决这个问题:
v2.8+ 和 v3.0+
从 v2.8
开始,我怀疑您可能会使用 AnswerType::class
,cascade_validation
已弃用。相反,您需要对 Question::$answers
class 成员应用 Valid
约束。像这样:
class Question
{
/**
* ... Other anotaions go here
*
* @Assert\Valid()
*/
private $answers
}
v2.8 之前的版本:
您需要指定cascade_validation
选项:
$builder
->add('title', TextType::class)
->add('answers', CollectionType::class, array(
'entry_type' => AnswerType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'cascade_validation' => true // <========= THIS
));
希望这对您有所帮助...