在我的Symfony项目中,我有一个权限Booking
,其中包含另一个实体Traveler
的集合。最少1人,最多4人。旅行者的数量可以由travelerCount
实体的字段Booking
指定。
class Booking {
/** @Assert\Range(min = 1, max = 4) */
private $travelerCount;
private $travelers = array();
// ...
}
我的预订表单控制器总是会向实体添加4位旅行者。我的表单BookingType
包含TravelerType
表单的嵌入式表单集(CollectionType
)。视图中的JavaScript会根据travelerCount
的值显示或隐藏旅行者。
通常我会使用@Assert\Valid
来验证旅行者收藏。但这不会在这里工作,因为我只想验证集合的第一个 travelerCount
(1-4)条目。例如,如果用户指定travelerCount
为2,则无法验证Traveler
s 3和4.否则,Traveler
中的@Assert\NotBlank
注释会出现验证错误}。
class Traveler {
/** @Assert\NotBlank */
private $firstName;
// ...
}
所以我的想法是不使用@Assert\Valid
。但是,如何从控制器手动调用嵌入式表单集合条目的验证?我想到了这样的事情:
for ($i = 0; $i < $booking->getTravelerCount(); ++$i) {
$this->get('validator')->startContext()
->atPath('booking.travelers['. $i .']')
->validate($booking->getTravelers()[$i]);
}
但是我不知道这是否会使错误出现在视图中,也不知道哪个参数值传递给atPath()
(我猜错了,但我确定我错了)
答案 0 :(得分:0)
在我的问题的评论中,LBA建议使用自定义验证器,我告诉他我有同样的问题:我不知道如何调用Traveler
验证约束注释的验证。好吧,我发现了如何:
class BookingValidator extends Symfony\Component\Validator\ConstraintValidator
{
public function validate($booking, Symfony\Component\Validator\Constraint $constraint)
{
for ($i = 0; $i < $booking->getTravelerCount(); ++$i) {
$this->context->getValidator()->inContext($this->context)
->atPath('travelers['. $i .']')
->validate($booking->getTravelers()[$i])
;
}
}
}
正如您所看到的,代码与我的问题中的代码类似。但是,我没有找到在控制器中执行此操作的方法。但同时我认为在一个单独的课程中进行验证是更好的风格,无论如何。