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);
    

我有两个名为 ArticleArticleTranslation 的实体具有 OneToMany 关系。创建Article 时,我想在其中添加ArticleTranslation(例如英语)- 这​​样至少提供了1 个翻译。文章本身只存储发布日期等通用数据,而翻译存储标题和内容(称为正文)。上面的代码工作正常,我唯一的问题是:

titlebody 的验证失败时,错误消息显示在公式上方,而不是在相关字段旁边。每个其他字段旁边都有正确的错误消息。我正在使用默认的 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,则该字段的任何错误都将附加到主表单,而不是特定字段。


您的 ArticleTranslationTypecompound,因此 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 验证:错误消息未显示在关联字段中的主要内容,如果未能解决你的问题,请参考以下文章

视图上未显示验证错误消息

我的验证错误消息未显示(Javascript)

如何在 Rails 验证错误中突出显示字段

Symfony 5 调试工具栏未显示在错误页面上

Symfony,在表单中预先提示/显示验证约束消息

当验证错误消息未在 ASP 页中触发时隐藏不必要的空间