我正在开发一个简单的Symfony API,但在设置两个实体之间的关系时遇到了麻烦。 我有两堂课:食谱和配料。 食谱可以包含许多成分,并且成分可以存在于许多食谱中,所以我使用了ManyToMany关联。
这是我的食谱课:
namespace RecipesBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Recipe
*
* @ORM\Table(name="recipe")
* @ORM\Entity(repositoryClass="RecipesBundle\Repository\RecipeRepository")
*/
class Recipe
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="description", type="string", length=255, nullable=true)
*/
private $description;
/**
* @var string
*
* @ORM\Column(name="image", type="string", length=255, nullable=true)
*/
private $image;
/**
* @ORM\ManyToMany(targetEntity="Ingredient", inversedBy="recipes")
* @ORM\JoinTable(name="recipes_ingredients")
*/
private $ingredients;
public function __construct() {
$this->ingredients = new ArrayCollection();
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Recipe
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* @param string $description
*
* @return Recipe
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set image
*
* @param string $image
*
* @return Recipe
*/
public function setImage($image)
{
$this->image = $image;
return $this;
}
/**
* Get image
*
* @return string
*/
public function getImage()
{
return $this->image;
}
/**
* Set ingredients
*
* @param array $ingredients
* @return Recipe
*/
public function setIngredients($ingredients) {
foreach($ingredients as $ingredient) {
$this->ingredients->add($ingredient);
}
return $this;
}
/**
* Get ingredients
*
* @return ArrayCollection
*/
public function getIngredients() {
return $this->ingredients;
}
}
这是我的成分课程:
namespace RecipesBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Ingredient
*
* @ORM\Table(name="ingredient")
*
@ORM\Entity(repositoryClass="RecipesBundle\Repository\IngredientRepository")
*/
class Ingredient
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @var int
*
* @ORM\Column(name="amount", type="integer")
*/
private $amount;
/**
* @ORM\ManyToMany(targetEntity="Recipe", mappedBy="ingredients")
*/
private $recipes;
public __construct() {
$this->recipes = new ArrayCollection();
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Ingredient
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set amount
*
* @param integer $amount
*
* @return Ingredient
*/
public function setAmount($amount)
{
$this->amount = $amount;
return $this;
}
/**
* Get amount
*
* @return int
*/
public function getAmount()
{
return $this->amount;
}
}
这是我的控制器:
class RecipeController extends Controller
{
/**
* @Route("/recipes")
*/
public function recipesAction(Request $request)
{
switch($request->getMethod()) {
case 'GET':
$recipes = $this->getDoctrine()->getRepository(Recipe::class)->findAll();
$return = $recipes;
break;
case 'POST':
$recipe = new Recipe();
$recipeData = json_decode($request->getContent(), true);
$recipe->setName($recipeData['name']);
$recipe->setDescription($recipeData['description']);
$recipe->setImage($recipeData['imagePath']);
$ingredients = $recipeData['ingredients'];
//var_dump($ingredients);die;
$recipe->setIngredients($ingredients);
//var_dump($recipe);die;
$em = $this->getDoctrine()->getManager();
$em->persist($recipe);
$em->flush();
$return = 'Recipe saved successfully';
break;
case 'PUT':
$recipes = json_decode($request->getContent(), true);
$em = $this->getDoctrine()->getManager();
foreach($recipes as $updating_recipe) {
$recipe = $this->getDoctrine()->getRepository(Recipe::class)->findOneBy(array('name' => $updating_recipe['name']));
if($recipe)
{
$recipe->setName($updating_recipe['name']);
$recipe->setDescription($updating_recipe['description']);
$recipe->setImage($updating_recipe['image']);
$recipe->setIngredients($updating_recipe['ingredients']);
$em->flush();
}
}
$return = 'Recipes saved successfully';
break;
case 'DELETE':
break;
}
return new JsonResponse($return);
}
}
当我尝试保存新配方(发布请求)时出现问题。 我收到以下错误:
关联字段“ RecipesBundle \ Entity \ Recipe#$ ingredients”的类型为“ Doctrine \ Common \ Collections \ Collection | array”的期望值,取而代之的是“ array”。
如果我正确使用setIngredients将成分添加到数组集合中,我不明白为什么会出现此错误。
关于什么可能是错误的任何想法? 预先感谢
编辑1:
我正在按要求添加配料转储:
array (size=1)
0 =>
array (size=2)
'name' => string 'Spaghetti' (length=9)
'amount' => int 10
答案 0 :(得分:0)
好,问题解决了。 正如萨米(Sami)所指出的,我不得不遍历所有的成分 在请求中,为每个对象创建一个成分对象。 然后将它们添加到ArrayCollection中,并使用$ recipe-> setIngredients();
进行设置非常感谢您的帮助。