我有实体广告系列和广告素材关系一个广告系列有很多广告素材
在广告系列中:
/**
* @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字段,我需要在刷新
之前保留广告系列答案 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))
。
删除它并开始工作