学说级联从反面持续

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);
            }
    }
}