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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 01:40:58