SonataAdminBundle с переводимыми полями (расширения доктрины)

у меня есть таблица со всеми переводами в таблице "ext_translations".

перевод работает отлично. Проблема в том, что теперь я хочу управлять этими переводами через sonata-admin bundle.

Я уже нашел документацию, как получить расширения доктрины работы с администратором sonata. Но в моем случае у меня есть одна таблица / сущность для всех моих переводов (для нескольких лиц).

Итак, согласно этой документации: http://www.elao.com/blog/symfony-2/doctrine-2/how-to-manage-translations-for-your-object-using-sonataadminbundle.html каким должен быть мой атрибут mappedBy (см. ниже)?

таблица ext_translations:

mysql> show columns from ext_translations;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| locale       | varchar(8)   | NO   | MUL | NULL    |                |
| object_class | varchar(255) | NO   |     | NULL    |                |
| field        | varchar(32)  | NO   |     | NULL    |                |
| foreign_key  | varchar(64)  | NO   |     | NULL    |                |
| content      | longtext     | YES  |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

MappedBy:

   /**
     * @ORMOneToMany(targetEntity="ProfileTranslation", mappedBy="object", cascade={"persist", "remove"})
     */
    protected $translations;

насколько я понял проблему здесь: "у меня есть составной ключ (objectclass (сущность) + имя (атрибута) + foreignKey (id сущности)), так как должен' mappedBy ' ссылаться на это?

Я не хочу создавать дополнительный класс для каждого переводимого объекта (как в учебнике сверху)

1 ответов


ваша ситуация довольно сложная. Вероятно, лучше всего может быть, если вы не используете anotation,переопределить класс репозитория, и построить всю свою собственную логику.

мы можем попытаться использовать новую способность с доктрины 2.1 создания составных составных ключей в качестве первичного ключа, как сказал Ферас в своем комментарии.

доктрина 2 изначально поддерживает составные первичные ключи. Составной ключ очень мощная концепция реляционной базы данных, и мы взяли хорошенько позаботиться чтобы убедиться, что доктрина 2 поддерживает как можно больше составного первичного ключа вариант использования. Для доктрины 2.0 составными ключами примитивных типов данных являются поддерживается, для доктрины 2.1 даже внешние ключи в качестве первичных ключей поддерживаемый.

в документах у нас есть хороший пример использования, который более или менее похож на ваш:

динамические атрибуты сущности (например, статья). каждая статья имеет много атрибутов с первичным ключом "идентификатором" и "имя атрибута."

вы можете увидеть пример здесь: http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-1-dynamic-attributes

но поскольку этот подход учитывает только одну сущность, мы должны адаптировать ее к вашим потребностям. Мы можем выполнить следующие шаги:

  1. создать этакий вид ext_translations таблица

    CREATE VIEW profile_ext_translations
    AS 
    SELECT * 
    FROM ext_translations
    WHERE  object_class = 'Profile'
    
  2. затем создать разные сущности, для этого представления, т. е. у вас будет сущность ProfileExtTranslations С составным первичным ключом, следующим образом:

    **
    * @Entity
    */
    class ProfileExtTranslations
    {
    
      /**
      * @ORM\ManyToOne(targetEntity="Profile", inversedBy="translations")   
      * @ORM\JoinColumn(name="foreign_key", referencedColumnName="id", onDelete="CASCADE")*/
       private $profile;
    
     /** @Id @Column(type="string") */
     private $field;
    
     //Other fields and methods
    
    
    }
    
  3. и теперь, код сущности профиля, в mappedBy переводов, вы просто используете:

    /**
    * @ORM\OneToMany(targetEntity="ProfileExtTranslation", mappedBy="profile", cascade={"persist", "remove"})
    */
    protected $translations;
    

и с этим и, вероятно, с небольшой настройкой, вы должны иметь его работу.