使用Symfony2更新鉴别器列Doctrine2

时间:2014-12-13 19:09:26

标签: mysql symfony inheritance doctrine-orm dql

我有一个名为User的实体,其中包含StudentProfessionalBusiness的继承。

当用户注册时,只有User但是他们必须更新他们的个人资料并选择哪种用户,我有一个处理这个的表单,一个获取表单数据的控制器,但我可以不要使用type

更新鉴别器字段$userEntity->setType()

这是我的映射资料

class User
{
    const TYPE_BASIC        = "Basico";
    const TYPE_STUDENT      = "Estudiante";
    const TYPE_PROFESSIONAL = "Profesional";
    const TYPE_BUSINESS     = "Empresa";

    protected $type = self::TYPE_BASIC;

    public function getType()
    {
        return self::TYPE_BASIC;
    }
    public function setType($type)
    {
        $this->type = $type;
    }

class Student extends User
{
    protected $type = self::TYPE_STUDENT;

然后专业和商业就像学生(改变const)

<entity name="User" table="user_base" inheritance-type="JOINED">
    <discriminator-column name="type" type="string"/>
    <discriminator-map>
        <discriminator-mapping value="Basico" class="User"/>
        <discriminator-mapping value="Estudiante" class="Student"/>
        <discriminator-mapping value="Profesional" class="Professional"/>
        <discriminator-mapping value="Empresa" class="Business"/>
    </discriminator-map>

子表名为user_xxx,其中xxx = Student/Professional/Business

这是我的控制器

    if($form->isValid())
    {
        $em         =   $this->getDoctrine()->getManager();

        $data       =   $form->all();
        $type       =   $data['type']->getData();
        $email      =   $data['email']->getData();
        $profile    =   $data['profile']->all();
        $name       =   $profile['name']->getData();
        $lastName   =   $profile['lastName']->getData();
        $birth      =   $profile['birth']->getData();

        $profileEntity  = new Profile();
        $profileEntity->setBirth($birth);
        $profileEntity->setName($name);
        $profileEntity->setLastName($lastName);
        $profileEntity->setUser($user);

        $em->persist($profileEntity);
        ladybug_dump($type);
        $userEntity =   $em->getRepository('User')->find($user);
        $userEntity->setProfile($profileEntity);
        $userEntity->setType($type);
        if($user->getEmail() != $email)
            $userEntity->setEmail($email);
        $em->persist($userEntity);

        $em->flush();

    }

一切都是持久的,但是type字段仍然是原始数据。我知道当我更改鉴别器列时,我需要在它的子元素中创建一个新行,但首先我想知道如何更改鉴别器列。

2 个答案:

答案 0 :(得分:0)

根据Doctrine documentation on Inheritance mapping,无法获取或设置类型。您可能希望利用PUGXMultiUserBundle,它可以轻松处理映射。此捆绑包还使您的用户可以使用适当的配置文件进行注册。

答案 1 :(得分:0)

如果您以Trait的形式使用此自定义代码,可以在存储库中使用,则是可能的。

特质:

namespace App\Doctrine\Repository;

use App\Exception\InvalidDiscriminatorClassException;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata;

/**
 * Discriminator Trait
 */
trait DiscriminatorTrait
{
    /**
     * @return ClassMetadata
     */
    abstract public function getClassMetadata();

    /**
     * @return EntityManager
     */
    abstract public function getEntityManager();

    /**
     * Update Discriminator Column
     *
     * @param integer $id
     * @param string $class
     * @return boolean
     * @throws InvalidDiscriminatorClassException
     */
    private function updateDiscriminatorColumn($id, $class)
    {
        /* @var ClassMetadata $classMetadata */
        $classMetadata = $this->getClassMetadata();

        if (!in_array($class, $classMetadata->discriminatorMap)) {
            throw new InvalidDiscriminatorClassException($class);
        }

        $identifier = $classMetadata->fieldMappings[$classMetadata->identifier[0]]["columnName"];

        $column = $classMetadata->discriminatorColumn["fieldName"];
        $value = array_search($class, $classMetadata->discriminatorMap);

        /* @var Connection $connection */
        $connection = $this->getEntityManager()->getConnection();

        try {
            $connection->update(
                $classMetadata->table["name"],
                [$column => $value],
                [$identifier => $id]
            );
        }
        catch (DBALException $e) {
            return false;
        }

        return true;
    }
}