学说级联从反面持续存在

时间:2015-09-23 11:24:56

标签: symfony doctrine-orm cascade

我与关联表有“多对多”的关系。来自父表的函数 calculDesCouts()正在计算成分的总成本,并在字段中保留此信息。实际上,由于关系的拥有和反面,当成分价格发生变化时,我无法级联持有父表。

这样做的正确方法是什么?我的意思是,当更新子行时,如何从父表触发持久回调?我知道我可以在我的控制器中做到这一点,使用这种成分的所有配方都有一个循环,但我真的想在ORM层上做这个...

这是我的父实体,在calculDesCouts上有生命周期回调:

returnByConstRef().bar

这是我的协会实体:

<?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;

}

1 个答案:

答案 0 :(得分:1)

我不知道如何在ORM级别上进行,但我会在Symfony2层上进行。 要做到这一点你需要的是创建一个EventListener,如果Ingredient的更新调用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);
            }
    }
}