学说级联从反面持续
Doctrine cascade persist from inversed side
我与一个协会 table 有 "many-to-many" 关系。来自父级 table 的函数 calculDesCouts() 正在计算 成分的总成本 ,并将此信息保存在字段中。实际上,由于关系的拥有和反面,当成分价格发生变化时,我无法级联坚持父 table。
正确的做法是什么?我的意思是,当更新子行时,如何触发来自父行的持久回调table?我知道我可以在我的控制器中做到这一点,在所有使用这种成分的食谱上循环,但我真的很想在 ORM 层上做到这一点...
这是我的父实体,在 calculDesCouts 上有一个生命周期回调:
<?php
/**
* @ORM\Table(name="recette")
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class Recette
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="\My\AcmeBundle\Entity\RecetteIngredientAssociation", mappedBy="recette", cascade={"persist"})
*/
protected $recette_ingredient_associations;
/**
* @ORM\Column(type="decimal", scale=2, nullable=true)
*/
private $cout_nourriture;
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function calculDesCouts()
{
$this->cout_nourriture = 0;
foreach ($this->recette_ingredient_associations as $ria) {
$this->cout_nourriture += $ria->getIngredient()->getPrix() * $ria->getQuantite();
}
}
}
这是我的协会实体:
<?php
/**
* @ORM\Table(name="recette_ingredient_association")
* @ORM\Entity
*/
class RecetteIngredientAssociation
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="\My\AcmeBundle\Entity\Recette", inversedBy="recette_ingredient_association")
* @ORM\JoinColumn(name="recette_id", referencedColumnName="id")
*
*/
private $recette;
/**
* @ORM\ManyToOne(targetEntity="\My\AcmeBundle\Entity\Ingredient", inversedBy="recette_ingredient_association")
* @ORM\JoinColumn(name="ingredient_id", referencedColumnName="id")
*/
private $ingredient;
/**
* @ORM\Column(type="decimal", scale=2, nullable=false)
*/
private $quantite;
}
这是我的子实体:
<?php
/**
* @ORM\Table(name="ingredient")
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class Ingredient
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="decimal", scale=2, nullable=true)
*/
private $prix;
/**
* @ORM\OneToMany(targetEntity="\My\AcmeBundle\Entity\RecetteIngredientAssociation", mappedBy="ingredient")
*/
protected $recette_ingredient_associations;
}
我不知道如何在 ORM 级别上进行,但我会在 Symfony2 层上进行。
为此,您需要创建一个 EventListener,它会在成分更新时调用 Recette 的 calculDesCouts。
赞声明服务:
app.ingredient_listener_update:
class: AppBundle\Listener\IngredientPriceListener
tags:
- { name: doctrine.event_listener, event: postUpdate }
并在此AppBundle\Listener\IngredientPriceListener中创建一个方法
public function postUpdate(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$em = $args->getEntityManager();
if ($entity instanceof Ingredient) {
foreach ($entity->get_recette_ingredient_associations() as $association)
foreach ($association->get_recettes() as $recette) {
$recette->calculDesCouts();
$em->persist($recette);
}
}
}
我与一个协会 table 有 "many-to-many" 关系。来自父级 table 的函数 calculDesCouts() 正在计算 成分的总成本 ,并将此信息保存在字段中。实际上,由于关系的拥有和反面,当成分价格发生变化时,我无法级联坚持父 table。
正确的做法是什么?我的意思是,当更新子行时,如何触发来自父行的持久回调table?我知道我可以在我的控制器中做到这一点,在所有使用这种成分的食谱上循环,但我真的很想在 ORM 层上做到这一点...
这是我的父实体,在 calculDesCouts 上有一个生命周期回调:
<?php
/**
* @ORM\Table(name="recette")
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class Recette
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="\My\AcmeBundle\Entity\RecetteIngredientAssociation", mappedBy="recette", cascade={"persist"})
*/
protected $recette_ingredient_associations;
/**
* @ORM\Column(type="decimal", scale=2, nullable=true)
*/
private $cout_nourriture;
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function calculDesCouts()
{
$this->cout_nourriture = 0;
foreach ($this->recette_ingredient_associations as $ria) {
$this->cout_nourriture += $ria->getIngredient()->getPrix() * $ria->getQuantite();
}
}
}
这是我的协会实体:
<?php
/**
* @ORM\Table(name="recette_ingredient_association")
* @ORM\Entity
*/
class RecetteIngredientAssociation
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="\My\AcmeBundle\Entity\Recette", inversedBy="recette_ingredient_association")
* @ORM\JoinColumn(name="recette_id", referencedColumnName="id")
*
*/
private $recette;
/**
* @ORM\ManyToOne(targetEntity="\My\AcmeBundle\Entity\Ingredient", inversedBy="recette_ingredient_association")
* @ORM\JoinColumn(name="ingredient_id", referencedColumnName="id")
*/
private $ingredient;
/**
* @ORM\Column(type="decimal", scale=2, nullable=false)
*/
private $quantite;
}
这是我的子实体:
<?php
/**
* @ORM\Table(name="ingredient")
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class Ingredient
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="decimal", scale=2, nullable=true)
*/
private $prix;
/**
* @ORM\OneToMany(targetEntity="\My\AcmeBundle\Entity\RecetteIngredientAssociation", mappedBy="ingredient")
*/
protected $recette_ingredient_associations;
}
我不知道如何在 ORM 级别上进行,但我会在 Symfony2 层上进行。 为此,您需要创建一个 EventListener,它会在成分更新时调用 Recette 的 calculDesCouts。
赞声明服务:
app.ingredient_listener_update:
class: AppBundle\Listener\IngredientPriceListener
tags:
- { name: doctrine.event_listener, event: postUpdate }
并在此AppBundle\Listener\IngredientPriceListener中创建一个方法
public function postUpdate(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$em = $args->getEntityManager();
if ($entity instanceof Ingredient) {
foreach ($entity->get_recette_ingredient_associations() as $association)
foreach ($association->get_recettes() as $recette) {
$recette->calculDesCouts();
$em->persist($recette);
}
}
}