You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony表单预设集合仅保存非空WeekDay实例的问题求解

解决方案

你只需要在表单数据绑定完成后、持久化到数据库前,过滤掉符合空规则的WeekDay实例即可,因为你的Week实体对days关联配置了orphanRemoval=true,被移除的空实例不会被持久化,原有已保存的空实例也会自动删除。

步骤1:确定空WeekDay的判断规则

根据你的业务场景自定义空实例的判定条件,示例规则如下(可自行调整):

  • used字段为false
  • 关联的themes为空
  • preparations配置为空

步骤2:添加表单事件过滤空实例

修改WeekType的buildForm方法,新增POST_SUBMIT事件监听,在表单数据完全绑定后移除空的WeekDay:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name')
        ->add('days', CollectionType::class, [
            'entry_type' => WeekDayType::class,
            'by_reference' => false,
            'allow_add' => true,
            'allow_delete' => true,
            'data' => $this->service->getAllSortedDays($builder->getData()),
        ])
    ;

    // 原有的SUBMIT事件保留,用来解决校验失败后展示不全的问题
    $builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
        $form = $event->getForm();
        $data = $event->getForm()->getData();

        $form
            ->add('days', CollectionType::class, [
                'entry_type' => WeekDayType::class,
                'by_reference' => false,
                'allow_add' => true,
                'allow_delete' => true,
                'data' => $this->service->getAllSortedDays($data),
            ])
        ;
    });

    // 新增POST_SUBMIT事件过滤空WeekDay
    $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
        /** @var Week $week */
        $week = $event->getData();
        foreach ($week->getDays() as $day) {
            // 此处判断规则可根据业务自行修改
            if (
                !$day->isUsed()
                && $day->getThemes()->isEmpty()
                && empty($day->getPreparations())
            ) {
                $week->removeDay($day);
            }
        }
    });
}

可选方案:控制器层面过滤

如果你不想在表单类里加逻辑,也可以在处理表单提交的控制器中,校验通过后、执行flush前手动过滤:

// 控制器中处理表单的代码示例
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
    /** @var Week $week */
    $week = $form->getData();
    // 过滤空WeekDay
    foreach ($week->getDays() as $day) {
        if (
            !$day->isUsed()
            && $day->getThemes()->isEmpty()
            && empty($day->getPreparations())
        ) {
            $week->removeDay($day);
        }
    }
    $entityManager->flush();
    // 后续逻辑...
}

内容的提问来源于stack exchange,提问作者Atyz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 05:06:04