简体   繁体   English

用Symfony2更新鉴别符列Doctrine2

[英]Update discriminator column Doctrine2 with Symfony2

I have an entity called User which has inheritance for Student , Professional and Business . 我有一个名为User的实体,该实体具有StudentProfessionalBusiness继承关系。

When a user is registered, is only a User but they must update their profile and choose which kind of user is, I have a form which handles this, a controller which gets the form data, but I can't update the discriminator field type with $userEntity->setType() 注册用户后,只有一个User但他们必须更新其个人资料并选择哪种用户,我有一个处理该表单的表单,一个获取表单数据的控制器,但是我无法更新区分字段type$userEntity->setType()

This is my mapping stuff 这是我的地图资料

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;

And then Professional and Business just like Student (changing const) 然后像学生一样更改专业和业务(更改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>

the child tables are named user_xxx where xxx = Student/Professional/Business 子表命名为user_xxx ,其中xxx = Student/Professional/Business

And this is my controller 这是我的控制器

    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();

    }

Everything is persisted but type field, which remains it's original data. 所有内容均保留,但type字段保留为原始数据。 I know when I change discriminator column I need to create a new row inside it's child element, but first I want to know how to change the discriminator column. 我知道更改标识符列时需要在其子元素内创建一个新行,但首先我想知道如何更改标识符列。

it is possible if you use this custom bit of code in the Form of a Trait which you can use inside a Repository. 如果您可以以代码形式使用此自定义代码,则可以在存储库中使用。

The 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;
    }
}

According to the Doctrine documentation on Inheritance mapping , it is not possible to either get or set the type. 根据有关继承映射Doctrine文档 ,无法获取或设置类型。 You may wish take advantage of PUGXMultiUserBundle , which readily handles the mapping. 您可能希望利用PUGXMultiUserBundle ,它可以轻松处理映射。 This bundle also makes it possible for your users to register with the appropriate profile. 此捆绑包还使您的用户可以使用适当的配置文件进行注册。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM