【问题标题】:Symfony ManyToOne relation change typeSymfony ManyToOne 关系更改类型
【发布时间】: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;
    }
}

【问题讨论】:

    标签: symfony orm entity dbal


    【解决方案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;或调用另一个函数/类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2014-05-05
    相关资源
    最近更新 更多