使用a2lix/TranslationFormBundle搭配#[Gedmo\Translatable]遇字段错误求助
问题:表单翻译字段报错
Field 'name' doesn't exist in App\Entity\ModuleTranslation 使用表单处理多语言翻译字段时触发报错:
Field 'name' doesn't exist in App\Entity\ModuleTranslation
系统要求ModuleTranslation类中存在name字段,但我们的翻译实体仅通过数据库存储字段引用,并未显式定义该字段,求解决方法。
相关代码
Module 实体类
#[Gedmo\TranslationEntity(class: ModuleTranslation::class)] class Module implements Translatable { use TimestampableEntity; #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: 'integer')] private $id; #[ORM\Column(name: 'name', type: 'string', length: "255")] #[Assert\NotBlank] #[Gedmo\Translatable] protected $name; #[ORM\Column(name: 'description', type: 'string', length: "255", nullable:true)] #[Assert\NotBlank] #[Gedmo\Translatable] protected $description; #[ORM\Column(name: 'active', type: 'boolean')] #[Gedmo\Translatable] protected $active; #[ORM\Column(name: 'module_order', type: 'integer')] private $order; #[ORM\Column(name: 'module_type', type: 'string', length: 255)] #[Assert\NotBlank] private $type; }
ModuleTranslation 实体类
class ModuleTranslation extends AbstractPersonalTranslation { public function __construct($locale, $field, $value) { $this->setLocale($locale); $this->setField($field); $this->setContent($value); } #[ORM\ManyToOne(targetEntity: Module::class, inversedBy: 'translations')] #[ORM\JoinColumn(name: 'object_id', referencedColumnName: 'id', onDelete: 'CASCADE')] protected $object; }
ModuleForm 表单类
class ModuleForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('translations', TranslationsType::class, [ 'fields' => [ 'name' => [ 'field_type' => 'text', 'label' => 'name.', 'locale_options' => [ 'en' => ['label' => 'Name'], 'pt' => ['label' => 'Nome'], ], 'attr' => [ 'class' => 'form-control', 'placeholder' => '', ] ], 'description' => [ 'field_type' => 'text', 'label' => 'description.', 'locale_options' => [ 'en' => ['label' => 'Description'], 'pt' => ['label' => 'Descrição'], ], 'attr' => [ 'class' => 'form-control', 'placeholder' => '', ] ], 'active' => [ 'field_type' => 'choice', 'label' => 'name.', 'locale_options' => [ 'en' => ['label' => 'Name'], 'pt' => ['label' => 'Nome'], ], 'attr' => [ 'class' => 'form-control kt-radio-inline', ], 'multiple' => false, 'expanded' => true, 'choices' => ModuleType::$activesAvailable, 'required' => true ], ], 'locale_labels' => [ 'pt' => 'Portuguese', 'en' => 'English', ], ]); $builder ->add('type', ChoiceType::class, [ 'attr' => [ 'label' => 'Module Type', 'id' => 'task-type', 'class' => 'kt-radio-inline', ], 'multiple' => false, 'expanded' => true, 'choices' => ModuleType::$typesAvailable, 'required' => true ]) ->add('quantity', TextType::class, [ 'attr' => [ 'label' => 'Quantity Type', 'class' => 'form-control', 'placeholder' => '' ], 'required' => false ]) ->add('icon', TextareaType::class, [ 'attr' => [ 'rows' => '8', 'label' => 'Icon Code', 'class' => 'form-control', ], 'required' => false ]) ->add('color', TextType::class, [ 'attr' => [ 'label' => 'Color', 'class' => 'form-control jscolor', 'placeholder' => '' ], 'required' => false ]) ; } }
解决方案
1. 给Module实体添加翻译集合映射
Gedmo翻译组件要求主实体必须显式关联翻译集合,当前Module类缺少该配置,补充代码:
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; #[Gedmo\TranslationEntity(class: ModuleTranslation::class)] class Module implements Translatable { // ... 现有代码 ... /** * @var Collection<int, ModuleTranslation> */ #[ORM\OneToMany(mappedBy: 'object', targetEntity: ModuleTranslation::class, cascade: ['persist', 'remove'])] private Collection $translations; public function __construct() { $this->translations = new ArrayCollection(); } public function getTranslations(): Collection { return $this->translations; } public function addTranslation(ModuleTranslation $translation): self { if (!$this->translations->contains($translation)) { $this->translations->add($translation); $translation->setObject($this); } return $this; } public function removeTranslation(ModuleTranslation $translation): self { if ($this->translations->removeElement($translation)) { if ($translation->getObject() === $this) { $translation->setObject(null); } } return $this; } }
2. 完善ModuleTranslation实体的ORM配置
确保继承Gedmo官方的抽象类,并补充必要的实体注解:
use Gedmo\Translatable\Entity\MappedSuperclass\AbstractPersonalTranslation; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] #[ORM\Table(name: 'module_translations')] #[ORM\UniqueConstraint(name: 'module_translation_unique_idx', columns: ['locale', 'object_id', 'field'])] class ModuleTranslation extends AbstractPersonalTranslation { public function __construct($locale, $field, $value) { $this->setLocale($locale); $this->setField($field); $this->setContent($value); } #[ORM\ManyToOne(targetEntity: Module::class, inversedBy: 'translations')] #[ORM\JoinColumn(name: 'object_id', referencedColumnName: 'id', onDelete: 'CASCADE')] protected $object; }
3. 修正表单的错误配置
表单中active字段的label配置错误,将name.改为对应标签:
'active' => [ 'field_type' => 'choice', 'label' => 'active.', 'locale_options' => [ 'en' => ['label' => 'Active'], 'pt' => ['label' => 'Ativo'], ], // ... 其他配置 ... ],
4. 清理缓存并更新数据库
执行命令使配置生效:
php bin/console cache:clear php bin/console doctrine:schema:update --force
内容的提问来源于stack exchange,提问作者gLanes
相关产品推荐
相关产品推荐

