2011-12-21 138 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此代碼才能正常工作。

當然,如果您採取這種方法,您的用戶界面不應該顯示一次完整編輯所有成分和數量的完整表格。相反,應列出所有成分,每行上有一個「刪除」按鈕以及一個「更改數量」按鈕,例如,該按鈕將彈出一個(單字段)表單以更新數量。