Symfony 验证:错误消息未显示在关联字段中
Posted
技术标签:
【中文标题】Symfony 验证:错误消息未显示在关联字段中【英文标题】:Symfony Validation: Error message not showing at associated field 【发布时间】:2021-06-13 16:30:53 【问题描述】:Symfony 5.2.5
精简代码
//Entities
class Article
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity=ArticleTranslation::class, mappedBy="article", cascade="persist", orphanRemoval=true)
* @Assert\Valid
*/
private $translations;
class ArticleTranslation
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank
*/
private $title;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank
*/
private $body;
/**
* @ORM\ManyToOne(targetEntity=Article::class, inversedBy="translations")
* @ORM\JoinColumn(nullable=false)
*/
private $article;
/**
* @ORM\Column(type="string", length=5)
* @Assert\NotBlank
*/
private $locale;
//FormTypes
class ArticleType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
$builder
->add(/*other fields*/)
->add('translations', ArticleTranslationType::class, ['label' => false, 'data' => new ArticleTranslation(), 'mapped' => false])
->add('save', SubmitType::class, ['label' => 'Save']);
$builder->get('translations')->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event)
$entity = $event->getForm()->getParent()->getData();
$translation = $event->getData();
$translation->setLocale($this->localeService->getCurrentLocale()); //custom service returns e.g. "en"
$entity->addTranslation($translation);
);
class ArticleTranslationType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
$builder
->add('title', TextType::class)
->add('body', TextareaType::class);
我有两个名为 Article
和 ArticleTranslation
的实体具有 OneToMany 关系。创建Article
时,我想在其中添加ArticleTranslation
(例如英语)- 这样至少提供了1 个翻译。文章本身只存储发布日期等通用数据,而翻译存储标题和内容(称为正文)。上面的代码工作正常,我唯一的问题是:
当title
或body
的验证失败时,错误消息显示在公式上方,而不是在相关字段旁边。每个其他字段旁边都有正确的错误消息。我正在使用默认的 bootstrap 4 表单主题。
如何将错误消息移至正确的字段? Symfony 分析器返回 data.translations[0].body
不应该为空(因为它是一个集合,它有一个索引) - 我想我需要以某种方式将它变成 data.translations.body
才能工作?
临时修复:在我的ArticleTranslationType
中添加验证并删除Assert\Valid
约束时,它可以工作。仍然对我提供的代码的另一种解决方案感兴趣 - 谢谢
【问题讨论】:
你有哪个版本的symfony?另外,如果你分享树枝部分会很有帮助 Symfony 5.2.5 - twig 只是一个通用的表单渲染 form(form)
。表单主题是默认的symfony github.com/symfony/symfony/blob/5.x/src/Symfony/Bridge/Twig/…
【参考方案1】:
您正在寻找的是error_bubbling FormType 字段选项。
错误冒泡
类型:boolean
默认:false
,除非是复合形式。
如果true
,此字段的任何错误都将传递给父字段或表单。例如,如果在普通字段上设置为true
,则该字段的任何错误都将附加到主表单,而不是特定字段。
您的 ArticleTranslationType 是 compound
,因此 error_bubbling 默认为 true
。
以下应该可以解决问题。
$builder->add(
'translations', ArticleTranslationType::class, array(
'data' => new ArticleTranslation(),
'error_bubbling' => false,
'mapped' => false,
'label' => false
)
);
【讨论】:
感谢您的回答,遗憾的是它似乎没有按我想要的方式工作。当将error_bubbling
设置为false
时,它确实不会将错误消息写入表单,但 它确实将其写入ArticleTranslationType
上方而不是相应的字段。例如,当我没有为 body
提供任何值时,错误消息会显示在我的 title
字段上方(因为它们都在自己的 FormType 中)。
快速更新:我通过为我的translations
提供property_path
得到了我的解决方案。我会为其他有同样问题的人回答。再次感谢:)
使用property_path
并不是真正的解决方案,因为在为一篇文章添加多个翻译时它仍然会失败。基本上,您希望将error_bubbling
设置为false
,以设置任何复合形式,尤其是在它们嵌套的情况下。此外,您应该查看CollectionType
以在表单中处理您的OneToMany
关联。
感谢您的回答。就我而言,每次只会添加 1 个翻译 - 这是我的目标。我故意跳过了CollectionType
。使用我当前的解决方案,它可以在使用默认 ArticleTranslation
创建 Article
以及稍后添加新的 ArticleTranslations
(只是一个带有 ArticleTranslationType 的表单)时工作。【参考方案2】:
在玩了之后,我终于找到了解决方案。由于验证尝试验证我的集合中的第一个元素,例如data.translations[0].body
我只需要提供正确的属性路径让它知道。
$builder->add(
'translations', ArticleTranslationType::class, array(
'data' => new ArticleTranslation(),
'mapped' => false,
'label' => false,
'property_path' => 'translations[0]' //first element of collection
)
);
这会将错误消息映射到相应的字段。
【讨论】:
以上是关于Symfony 验证:错误消息未显示在关联字段中的主要内容,如果未能解决你的问题,请参考以下文章