使用EntityType显示选择时,无法从Symfony表单保存实体

问题描述 投票:1回答:1

我的symfony项目中有两个相关实体 - 使用Doctrine存储。一个实体是“广告商”,其具有ID和名称。导致问题的另一个实体是“报告”,它具有自己的ID以及名为“advertiser_id”的字段。

为广告客户添加报表时,在Symfony表单中,我使用EntityType作为advertiser_id字段,以便我可以显示一组广告客户。这部分工作得很好,但是当我尝试提交表单时,我收到错误,因为它将广告客户对象而不是广告客户的ID传递给advertiser_id字段。

这是我在表单构建器中的内容:

$builder
    ->add('advertiser_id', EntityType::class, [
        'class'        => Advertiser::class,
        'query_builder' => $this->advertiserRepository->findAllNotDeletedUnpaginated(),
        'choice_label' => 'name',

    ])
    ->add('submit', SubmitType::class, [
        'label' => 'Submit',
    ])
;

当我提交表单时,我收到此错误:给出了“整数”,“App \ Entity \ Advertiser”类型的预期参数。

关于如何强制symfony只尝试保存所选广告客户的ID而不是传递整个广告客户的任何想法?

更新:现在我已经重构了它,以便广告客户是一个报告的相关实体,我正在试图弄清楚如何让广告客户成为一个隐藏的领域并且无处可去。

我已经尝试过iiirxs之前提到的回调变换器代码 - 将'advertiser_id'更改为'advertiser' - 但我没有运气。我一直在阅读像Symfony hiddenType using data_class for entity instead of transformer这样的帖子,但是我很难在这个例子中获得“广告客户”的价值,因为他们获得了$ options ['selected_course']。

当我尝试(出于测试目的)为广告客户硬编码值1,然后将其放在表单上时,表单会显示,但在提交时会出错:

    $advertiser=1;

    $builder
        ->add('advertiser', HiddenType::class,['data' => $advertiser, 'data_class' => null])

我在提交表单时遇到的错误是:给出了“App \ Entity \ Advertiser”或“null”类型的预期参数。

我很抱歉打这个死马。这似乎应该是一个常见/容易的事情,但我很难找到如何使它成为一个隐藏的领域。任何想法将不胜感激!

symfony symfony-forms
1个回答
0
投票

问题是您没有在报表实体中正确定义与广告商实体的关联。您应该已经定义了这样的关联:

// inside Report.php class

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\Advertiser")
 */
private $advertiser;

而不是定义一个包含外键advertiser_id的字段。 Doctrine足够聪明,可以将广告商字段映射到数据库中的advertiser_id外键,因此最好使用关联映射。你可以在documentation找到更多。

但是,如果您确实只需要使用整数将advertiser_id存储为整数,则应使用Symfony的Data Transformer将广告客户实体转换为如下整数:

$advertiserRepository = $this->advertiserRepository;
$builder->get('advertiser_id')
        ->addModelTransformer(new CallbackTransformer(
            function ($advertiserAsInteger) use ($advertiserRepository) {
                // transform the integer to an entity object
                return $advertiserRepository->find($advertiserAsInteger);
            },
            function ($advertiserAsEntity) {
                // transform the entity back to an integer
                return $advertiserAsEntity->getId();
            }
        ))
    ;

在上面的代码中,我使用CallbackTransformer来实现转换,但您也可以使用转换器类来实现转换。你可以在data transformers documentation找到更多相关信息。

© www.soinside.com 2019 - 2024. All rights reserved.