symfony - 使用 EntityType 显示选择时,无法从 Symfony 表单中保存实体
问题描述
我的 symfony 项目中有两个相关的实体——它们是使用 Doctrine 存储的。一个实体是“广告商”,它有一个 ID 和一个名称。另一个导致问题的实体是一个“报告”,它有一个自己的 id 以及一个名为“advertiser_id”的字段。
在为广告商添加报告时,在 Symfony 表单中,我使用 EntityType 作为advertisingr_id 字段,以便我可以显示选择的广告商。那部分工作得很好,但是当我尝试提交表单时,我收到一个错误,因为它正在将一个 Advertiser 对象而不是广告商的 id 传递给 adser_id 字段。
这是我在表单构建器中的内容:
$builder
->add('advertiser_id', EntityType::class, [
'class' => Advertiser::class,
'query_builder' => $this->advertiserRepository->findAllNotDeletedUnpaginated(),
'choice_label' => 'name',
])
->add('submit', SubmitType::class, [
'label' => 'Submit',
])
;
当我提交表单时,我收到了这个错误:Expected argument of type "integer", "App\Entity\Advertiser" given。
关于如何强制 symfony 仅尝试保存所选广告商的 id 而不是传递整个广告商的任何想法?
更新:现在我已经对其进行了重构,以便广告商是要报告的相关实体,我正在尝试弄清楚如何使广告商成为隐藏字段并且无处可去。
我已经使用回调转换器尝试了之前提到的 iiirxs 的代码——将“advertiser_id”更改为“advertiser”——但我没有运气。我一直在阅读像Symfony hiddenType 这样的帖子,使用 data_class for entity 而不是transformer,但是我无法像在该示例中获取 $options['selected_course'] 那样获取 'advertiser' 的值。
当我尝试(出于测试目的)为广告客户硬编码值 1,然后将其放在表单上时,表单会显示,但在提交时出现错误:
$advertiser=1;
$builder
->add('advertiser', HiddenType::class,['data' => $advertiser, 'data_class' => null])
提交表单时出现的错误是:“App\Entity\Advertiser 或 null”类型的预期参数,给出了“字符串”。
我很抱歉在这件事上打了一匹死马。这似乎应该是一件很常见/容易做的事情,但我很难找到如何让它成为一个隐藏的领域。任何想法将不胜感激!
解决方案
问题是您没有在 Report 实体中正确定义与 Advertiser 实体的关联。您应该已经定义了这样的关联:
// inside Report.php class
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Advertiser")
*/
private $advertiser;
而不是定义一个包含外键的字段advertiser_id
。Doctrine 足够聪明,可以advertiser_id
自行将广告客户字段映射到数据库中的外键,因此最好使用关联映射。您可以在文档中找到更多信息。
但是,如果您出于自己的原因确实必须仅使用整数将 存储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 来实现转换,但您也可以使用转换器类来实现。您还可以在数据转换器文档中找到更多相关信息。
推荐阅读
- go - 在 Go 中创建任意切片类型的 stringer 方法
- java - JavaFX WebEngine - 无法加载本地存储的 firebug-lite.js
- java - 使用 kotlin 在菜单中制作可点击的链接
- php - 如何使用静态方法运行构造函数
- java - 在android中膨胀类ImageView时出错
- matrix - 户主变换-QR分解
- openstack - Openstack sahara:撒哈拉仪表板
- php - 将 PHP 脚本从 mysqli 重写为 pdo 代码
- javascript - 如何使用数据属性中的两个或多个值过滤(显示/隐藏)
- openhab - openhab2 openhabmin 安装