从阵列集合中分离出一对多的学说

时间:2018-02-16 19:37:30

标签: php doctrine

我有实体广告系列和广告素材关系一个广告系列有很多广告素材

在广告系列中:

/**
 * @ORM\OneToMany(targetEntity="Creative", mappedBy="campaign", cascade={"detach", "persist"})
 */
protected $creatives;

在广告素材中

/**
 * @ORM\ManyToOne(targetEntity="Campaign", inversedBy="creatives", cascade={"detach", "persist"})
 * @ORM\JoinColumn(name="campaign_id", referencedColumnName="id")
 */
private $campaign;

在前端,我有多个选择,我可以添加/删除广告素材,并向后端发送一组广告素材ID。

问题是当我从选择中删除一个时,如何从广告系列中分离广告素材。

我没有找到任何解释什么原则可以提出,所以我试过:

$campaign->getCreatives()->clear();
foreach (json_decode($data['creatives'],true) as $creativeId) {
    $campaign->addCreative($this->_em->getReference(Creative::class, $creativeId));
}

但看起来它不起作用,代码从Campaign对象中删除元素,但不将campaign_id更改为null,以用于数据库中的相关广告素材。也许我还需要将它从Creative端分离,但这是额外的工作,我认为cascade = {“detach”}应该处理它。

我将不胜感激任何帮助!!!

仅供参考:我正在使用Laravel的学说。

更新 我在Campaign中创建了同步方法作为解决方法:

public function syncCreatives(array $creatives)
{
    //detach all creatives
    if(empty($creatives)) {
        /** @var Creative $creative */
        foreach ($this->creatives->getIterator() as $creative) {
            $creative->setCampaign(null);
        }
        $this->creatives->clear();

        return true;
    }
    //get nonexistent creatives
    $creativesToRemove = $this->creatives->filter(function (Creative $creative) use (&$creatives) {
        if(isset($creatives[$creative->getId()])) {
            unset($creatives[$creative->getId()]);

            return false;
        }

        return true;
    });
    //remove nonexistent creatives
    foreach ($creativesToRemove->getIterator() as $creative) {
        $this->removeCreative($creative);
    }
    //add new creatives
    foreach ($creatives as $creative) {
        $this->addCreative($creative);
    }
}

相关方法:

 /**
 * @param Creative $creative
 */
public function removeCreative(Creative $creative)
{
    if($this->creatives->contains($creative)) {
        $creative->setCampaign(null);
        $this->creatives->removeElement($creative);
    }
}

/**
 * @param Creative $creative
 */
public function addCreative(Creative $creative)
{
    if(!$this->creatives->contains($creative)) {
        $this->creatives->add($creative);
        $creative->setCampaign($this);
    }
}

所以现在我正在更新广告系列和广告素材对象,但仍然没有从广告系列中分离广告素材

更新即可。我发现了这篇文章Doctrine: How to unset (SET NULL) OneToMany relationship,但我不知道我的代码和解决方案之间有什么区别?我不应该坚持使用?但在我的逻辑中,我更新了很多Campaign字段,我需要在刷新

之前保留广告系列

1 个答案:

答案 0 :(得分:0)

好的,我找到了什么是ussie。这是我的错:(

在Cretive我有代码

/**
 * @param Campaign $campaign
 */
public function setCampaign(Campaign $campaign = null)
{
    if(!is_null($campaign)) {
        $this->campaign = $campaign;
        $this->campaign->addCreative($this);
    }

}

我不记得我何时以及为何添加此if(!is_null($campaign))

删除它并开始工作