Symfony2 FOSUserBundle Ограничение поля пользовательского объекта

У меня проблема с переопределением сущности. Мне нужно, чтобы поле emailCanonical не было уникальным.

Вот что я сделал: в моем UserBundle\Resources\config\doctrine\User.orm.xml я добавил следующую конфигурацию attribute-overrides, согласно документации Doctrine2

<attribute-overrides>
    <attribute-override name="emailCanonical">
        <field column="email_canonical" unique="false" name="emailCanonical" />
    </attribute-override>
</attribute-overrides>

Затем я выполнил следующие команды консоли

$ php app/console doctrine:migrations:diff
$ php app/console doctrine:migrations:migrate

Все работало нормально. emailCanonical был сделан не уникальным. Но теперь, когда мне нужно создать объект в других пакетах проекта, у меня есть странная ошибка:

 $ php app/console doctrine:generate:entities SkyModelsBundle:Category
 Generating entity "Sky\Bundle\ModelsBundle\Entity\Category"

 [Doctrine\ORM\Mapping\MappingException]
 Invalid field override named 'emailCanonical' for class 'Sky\Bundle\UserBundle\Entity\User'.

 doctrine:generate:entities [--path="..."] [--no-backup] name

Однако, если я удалю настройки переопределения из сопоставления xml, все будет хорошо.

Ответ 1

Вы переопределяете использование аннотаций PHP таким образом (это поддерживается, начиная с доктрины версии 2.3 и выше, обратите внимание, что в документации упоминается, что вы не можете переопределять типы, однако я смог сделать это, используя последнюю версию доктрины, в то время написания 2.4.4):

<?php 
namespace Namespace\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use FOS\UserBundle\Model\User as BaseUser;

/**
 * User
 * @ORM\Entity
 * @ORM\AttributeOverrides({
 *     @ORM\AttributeOverride(name="id",
 *          [email protected]\Column(
 *              name     = "guest_id",
 *              type     = "integer",
 *              length   = 140
 *          )
 *      )
 * })
 */
class myUser extends BaseUser
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
}

Это указано в документации по адресу: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html#overrides

Ответ 2

Цитата из официальной документации, поэтому может быть ее единственным способом.

Если вам нужно изменить сопоставление (например, для адаптации имен полей к устаревшей базе данных), единственным решением будет написать все сопоставление снова, не наследуя отображение из сопоставленного суперкласса.

Ответ 3

Я считаю, что атрибут name тега field не требуется, поскольку он уже указан для тега attribute-override

Попробуй это

<attribute-overrides>
    <attribute-override name="emailCanonical">
        <field column="email_canonical" unique="false" />
    </attribute-override>
</attribute-overrides>

Ответ 4

Кажется, что объекты FOSUserBundle импортируются неправильно в ваш проект. Убедитесь, что FOSUserBundle присутствует в разделе "сопоставления" (ветка "доктрина") вашего config.yml

doctrine:
    orm:
        entity_managers:
            default:
                connection:       default
                mappings:
                    AcmeDemoBundle: ~
                    FOSUserBundle: ~

Ответ 5

У меня была такая же ошибка сейчас, и я решил ее. Doctrine выбрасывает это Mappingexception в ClassMetadataInfo, когда он не может найти связанное свойство (атрибут или отношение) в его сопоставлении.

Итак, чтобы переопределить атрибут "emailCanonical", вам необходимо использовать "атрибуты-переопределения" и "атрибут-переопределить" (как и вы) и переопределить свойство класса php в своей сущности:

<?php
...
class YourUser extends BaseUser
{
    ...
    /**
     * Email canonical
     *
     * @var string
     *
     * @ORM\Column(name="email_canonical", type="string", length=255, unique=false)
     */
    protected $emailCanonical;

@EDIT: использование этого решения вызывает у меня еще одну ошибку.

Он решил проблему "Недопустимое переопределение поля с именем...", но при попытке проверить схему с помощью php app/console doctrine:schema:validate, я получил еще один вариант с "Дубликат определения столбца...".

Есть идеи?

Ответ 6

Ваш класс, расширяющий BaseUser, должен выглядеть следующим образом:

<?php 
namespace Namespace\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
 * User
 * @ORM\Entity
 * @ORM\Table(name="user")
 * @UniqueEntity(fields="email", message="your costum error message")
 *
 */
class myUser extends BaseUser
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
}

?>

Ответ 7

Я знаю, что это старый пост, но я нашел решение, по крайней мере, это сработало для меня, возможно, это было бы полезно для кого-то другого.

Ну, у меня была такая же проблема, и я использую собственный менеджер для fos_user, в файле декларации config.yml в соответствии с пользовательским менеджером doctrine entity_manager. Я объявил сопоставление с FOS_userBundle, НО чего не было, - сообщить FOS_user, что мы используем, и добавив:

fos_user:
---- db_driver: orm
---- model_manager_name: MyCustom_Manager