2011-12-21 2 views
0

이것에 대한 토론을 찾지 못했기 때문에 이것은 정말로 기본적인 것들이어야합니다. 그러나 나는 잠시 동안 이것으로 고생했다.doctrine2 엔티티 업데이트

this example (이중 일대 다 관계)와 같이 구현 된 추가 필드가있는 매우 기본적인 다 대다 관계가 있습니다. 이것은 새로운 엔터티를 생성하고 데이터베이스에 저장할 때 잘 작동합니다. 편집 기능을 만들려고하고 있는데 문제가 생겼습니다.

내 주요 엔티티는 Recipe라고하는데, Ingredient 엔티티와 다 대다 관계가 있습니다. "amount"와 같은 추가 필드는 RecipeIngredient 엔티티에 있습니다. 레시피 클래스에는 성분 배열에 RecipeIngredient 객체를 추가하는 setRecipeIngredient 메소드가 있습니다.

모든 "RecipeIngredient"객체를 제거하는 "clearRecipeIngredients"메소드를 레서피 클래스에 만들어야합니까? Recipe를 편집 할 때 이것을 호출하고, 새로운 데이터를 생성하고 새로운 엔티티를 생성 할 때와 같이 재료 배열을 채우는 새로운 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해야합니다.

물론이 방법을 사용하면 UI에 모든 재료와 수량을 편집 할 수있는 전체 양식이 한 번에 표시되지 않아야합니다. 대신, 각 성분에 "삭제"버튼과 함께 수량을 업데이트하기 위해 (단일 필드) 양식을 팝업하는 "수량 변경"버튼과 같이 모든 성분이 나열되어야합니다.