forms - 由于存储库中的意外实体更改时间,Symfony 表单自定义约束评估失败
问题描述
在 Symfony 3.3.17 应用程序中,我有一个带有使用自定义验证约束的参数的实体
class JobAd
{
...
/**
* @ORM\Column(type="string", length=2048)
* @JobAdAssert\JobAdUrlExists
*/
protected $url = '';
...
}
约束 JobAdUrlExists 看起来像这样
/**
* @Annotation
*/
class JobAdUrlExists extends Constraint
{
public $message = 'Cant use URL "{{ string }}". Its in use already.';
public function validatedBy()
{
return 'job_add_url_exists.validator';
}
}
这是 JobAdUrlExistsValidator
class JobAdUrlExistsValidator extends ConstraintValidator
{
// ...
public function validate( $value, Constraint $constraint )
{
// ...
if( /* logic here */ ) {
$this->context->buildViolation( $constraint->message )
->setParameter( '{{ string }}', $value )
->addViolation();
}
}
}
表单类型定义为
class JobAdType extends AbstractType implements ContainerAwareInterface
{
use ContainerAwareTrait;
public function buildForm( FormBuilderInterface $builder, array $options )
{
// ...
$builder->add( 'url', TextType::class, array(
'label' => $translator->trans( 'URL' ),
'required' => false,
'translation_domain' => 'messages',
'mapped' => true,
'data' => $url
));
// add other form fields ...
}
public function configureOptions( OptionsResolver $resolver )
{
$resolver->setDefaults(
array(
'data_class' => 'AppBundle\Entity\JobAd',
)
);
}
public function getBlockPrefix()
{
return 'job_ad';
}
}
我的应用程序逻辑创建一个这样的视图
// ...
$jobAd = $jobAdRepository->findOneBy( array( 'url' => $job_ad_url ) );
$jobAdForm = $this->createForm( JobAdType::class, $jobAd );
if('POST' === $request->getMethod()) {
if( $request->request->has( 'job_ad' ) ) {
$jobAdForm->handleRequest($request);
if( $jobAdForm->isSubmitted() && $jobAdForm->isValid() ) {
// ...
$em->persist( $jobAd );
$em->flush();
}
}
}
return $this->render( $jobAdTemplate, array(
'form_job_ad' => $jobAdForm->createView(),
));
最后 - 树枝视图输出这样的形式
{{ form_start(form_job_ad) }}
{{ form_errors(form_job_ad) }}
{{ form_widget(form_job_ad.url) }}
{{ form_end(form_job_ad) }}
现在 - 当我在表单字段中插入一个触发验证错误的 URL 时,会发生三件事让我很困惑:
- JobAdUrlExistsValidator 中的 validate 方法构建违规。但是,在评估 URL 是否存在时,我获取了现有的 JobAd,令人惊讶的是,代表现在与表单一起呈现的 JobAd 的 URL 参数已经设置为新的(并且可能是错误的)URL。这是否意味着在验证实际发生之前更改了用于填写表单的基本实体?
- 尽管对 $jobAdForm->isValid() 的调用没有返回 true,因此 $em->persist() 和 $em->flush() 都没有被调用,但前端的表单不会输出任何错误并显示新的 URL作为其预设值。然而,代表实体的 DB 条目不会改变 - 因此当再次加载页面时,URL 又是旧的。
- 当输入一个在被约束检查时不应该失败的 URL 时,验证也会说这也是一个错误。当记住 1 中的观察时,这并不奇怪。)-> 实体的 URL 参数在实际检查任何内容之前已更改,因此在检查新 url 是否已经存在时,它显然会失败,因为它确实存在 - 在条目中它应该是现在插入。
我现在很困惑,有点绝望,不知道在哪里寻找问题的解决方案......非常欢迎任何提示:-)
解决方案
推荐阅读
- google-cloud-platform - 如何将 GCP 中的 VPC 流日志设置为始终开启?
- docusignapi - 如何查看从docusign 下载的PDF 文件?
- ssis - SSIS连接时间戳列和整数
- python - 从映射列表创建新字典到字典
- ssl - 使用 mitmproxy 从 pcap 文件中读取网络流量以进行 SSL 检查
- android - Android Studio - 使用 retrofit2 从 restdb 获取信息
- javascript - 多次使用 parentElement
- r - 计算R中同一行中2个坐标之间的距离
- reactjs - React Router 链接在 ReactJS 和 Mobx 中使用 react-router-dom 的 Menu.Item 元素中不起作用
- mediawiki - 为什么即使此模块已导入我的 MediaWiki 中,也会出现错误“脚本错误:没有此类模块“en-headword””?