2011-12-21 67 views
0

这一定是非常基本的东西,因为我没有发现任何关于它的讨论。不过,我一直在努力。更新doctrine2实体

我有很多基本的多对多的关系,像在this example(double一对多关系)中实现的额外字段。这在创建新实体并将其保存到数据库时很好地工作。我正在尝试创建编辑功能并遇到一些问题。

可以说我的主要实体称为食谱,它与成分实体有多对多的关系。额外字段(如“amount”)在RecipeIngredient实体中。食谱类有setRecipeIngredient方法,它将RecipeIngredient对象添加到配料数组中。

我应该为Recipe类创建一些“clearRecipeIngredients”方法,它将删除所有RecipeIngredient对象吗?编辑食谱时,我会调用它,然后从我的数据创建新的RecipeIngredient实体,并在创建新实体时填充配料数组?我承认我的级联设置可能没有正确设置,但我尝试着下一步修复它。

任何相关的例子都会很棒。

回答

1

严格来说,正如你所提到的,这里没有多对多的关系,而是一对多之后是多对一的关系。

关于你的问题,每次我想编辑食谱时,我都不会执行批量“清除”操作。相反,如果您想编辑基于纸张的配方,我会提供一个流畅的界面来模仿将要采取的步骤。

我下面提供的实现:

class Recipe 
{ 
    /** 
    * @OneToMany(targetEntity="RecipeIngredient", mappedBy="recipe") 
    */ 
    protected $recipeIngredients; 

    public function addIngredient(Ingredient $ingredient, $quantity) 
    { 
    // check if the ingredient already exists 
    // if it does, we'll just update the quantity 
    $recipeIngredient = $this->findRecipeIngredient($ingredient); 
    if ($recipeIngredient) { 
     $quantity += $recipeIngredient->getQuantity(); 
     $recipeIngredient->updateQuantity($quantity); 
    } 
    else { 
     $recipeIngredient = new RecipeIngredient($this, $ingredient, $quantity); 
     $this->recipeIngredients[] = $recipeIngredient; 
    } 
    } 

    public function removeIngredient(Ingredient $ingredient) 
    { 
    $recipeIngredient = $this->findRecipeIngredient($ingredient); 
    if ($recipeIngredient) { 
     $this->recipeIngredients->removeElement($recipeIngredient); 
    } 
    } 

    public function updateIngredientQuantity(Ingredient $ingredient, $quantity) 
    { 
    $recipeIngredient = $this->findRecipeIngredient($ingredient); 
    if ($recipeIngredient) { 
     $recipeIngredient->updateQuantity($quantity); 
    } 
    } 

    protected function findRecipeIngredient(Ingredient $ingredient) 
    { 
    foreach ($this->recipeIngredients as $recipeIngredient) { 
     if ($recipeIngredient->getIngredient() === $ingredient) { 
     return $recipeIngredient; 
     } 
    } 
    return null; 
    } 
} 

注意:您需要设置cascade persistorphan removal此代码才能正常工作。

当然,如果您采取这种方法,您的用户界面不应该显示一次完整编辑所有成分和数量的完整表格。相反,应列出所有成分,每行上有一个“删除”按钮以及一个“更改数量”按钮,例如,该按钮将弹出一个(单字段)表单以更新数量。