Symfony ManyToOne 关系更改类型

Posted

技术标签:

【中文标题】Symfony ManyToOne 关系更改类型【英文标题】:Symfony ManyToOne relation change type 【发布时间】:2021-03-10 11:24:21 【问题描述】:

我有 2 个实体,其中 1 个由 Symfony 管理,其他则不是

不受 Symfony 管理的实体

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * User
 *
 * @ORM\Table(name="p_user")
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 */
class User

    /**
     * @var int
     *
     * @ORM\Column(name="user_id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var Permission
     *
     * @ORM\ManyToOne(targetEntity="Permission", inversedBy="user", cascade="persist", "remove")
     * @ORM\JoinColumn(name="permission_id", referencedColumnName="permission_id", onDelete="CASCADE")
     */
    private $permission;

Symfony 管理的实体

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * Permission
 *
 * @ORM\Table(name="p_permission")
 * @ORM\Entity(repositoryClass="App\Repository\PermissionRepository")
 */
class Permission

    /**
     * @var int
     *
     * @ORM\Column(name="permission_id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var ArrayCollection
     *
     * @ORM\OneToMany(targetEntity="User", mappedBy="permission", cascade="persist", "remove", orphanRemoval=true)
     */
    private $user;

我需要保存User实体但permission不能为空,当没有关系时,值设置为0。

经过我的研究,我发现User::permission 接收类型为Permission::id,但我希望User::permission 类型为nullidentity

PS: Null\IdentityType

namespace App\DBAL\Types\Null;

use Doctrine\DBAL\Types\IntegerType as DeafaultType;
use Doctrine\DBAL\Platforms\AbstractPlatform;

class IdentityType extends DeafaultType

    const NULLIDENTITY = 'nullidentity';

    public function getName()
    
        return self::NULLIDENTITY;
    

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    
        // dd($this);
        return $value === null? 0: (int)$value;
    

    public function convertTophpValue($value, AbstractPlatform $platform)
    
        return $value === 0? null: (int)$value;
    

【问题讨论】:

【参考方案1】:

在 symfony 中,验证实体的最佳实践是 Doctrine Event Subscribers。

您可以创建一个订阅者并检查、更改、删​​除、插入或运行您喜欢的代码。您有事件而不是触发持久化、更新或刷新。

对于您的问题,只需验证实体并根据需要进行更改。

编辑

根据要求添加一个示例。

首先你必须在 service.yaml 中注册它

App\EventSubscribers\EntitySubscriber:
   tags:
     -  name: doctrine.event_subscriber, connection: default

然后创建一个这样的类

class EntitySubscriber implements EventSubscriber

public function getSubscribedEvents()

    return [
        Events::prePersist
    ];


public function prePersist(LifecycleEventArgs $args)

  /*Continue for other entities or add the user entity in the if statement*/
    if (!$args->getObject() instanceof Permission) 
        return;
    
     
      /*Do what you need here, use the $args for more options*/

 

您可以找到所有活动here

【讨论】:

有例子吗?因为我这样做但不明白如何实现。 @ORM\HasLifecycleCallbacks()@ORM\PrePersist()@ORM\PreUpdate() 查看我的编辑并在实体之外尝试。在那里,您可以在construct() 中插入您想要的所有类,并将其添加到您想要检查的所有实体中。提示:尝试为小型作业创建特定的订阅者,因为它们都同时运行并且在调试中很难找到。 它对我帮助不大,因为我无法设置 $this->permission = 0,它的类型错误 正如我在评论中所建议的,您需要使用 $args 变量来获取当前实体 $entity=$args->getObject();然后改变它 $enitity->setPermision(0);或 $entity->permission =0;或调用另一个函数/类。

以上是关于Symfony ManyToOne 关系更改类型的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine symfony使用OneToMany删除实体 - ManyToOne关系

Symfony 5 easyadmin 3 与 ManyToOne 关系的实体 - 不保存在“多”端

Symfony嵌入了ManyToOne关系

Doctrine ManyToOne 关系 - 在“设置”时自动删除

ORM Doctrine ManyToOne on update CASCADE (Symfony)

Symfony 3 - Doctrine 2 - 在 oneToMany 关系上的 orderBy 不起作用