Symfony5:使用 REST API 保存相关的 (oneToMany) 实体

Symfony5: save related (oneToMany) entity with REST API

我有两个实体 类:产品和价格。产品有很多价格。关系定义为(仅显示相关代码):

Product.php

public function __construct()
{
    $this->prices = new ArrayCollection();
}

/**
 * @var Collection|Price[]
 * @ORM\OneToMany(targetEntity="Price", mappedBy="product", cascade={"persist", "remove"})
*/
private Collection $prices;

/**
 * @return Collection|Price[]
 */
public function getPrices()
{
    return $this->prices;
}

/**
 * @param Collection|Price[] $prices
 */
public function setPrices(Collection $prices) : void
{
    $this->prices = $prices;
}

Price.php

/**
 * @ORM\ManyToOne(targetEntity="Product", inversedBy="prices")
*/
private Product $product;

public function getProduct() : Product
{
    return $this->product;
}

public function setProduct(?Product $product) : self
{
    $this->product = $product;
    return $this;
}

ProductType::buildForm()

$builder
->add('prices', EntityType::class, [
    'class' => Price::class,
    'multiple' => true,
    'constraints' => [
        new NotNull(),
    ],
]);

ProductController::add()

public function add(Request $request, EntityManagerInterface $manager) : Response
{
    $form = $this->container->get('form.factory')->createNamed('', ProductType::class);
    $form->handleRequest($request);

    if (! $form->isSubmitted() || !$form->isValid()) {
        return $this->handleView($this->view($form, Response::HTTP_BAD_REQUEST));
    }

    /** @var Product $product */
    $product = $form->getData();

    $manager->persist($product);
    $manager->flush();

    return $this->respond($product, Response::HTTP_CREATED);
}

请求JSON

{
  "name": "added",
  "prices": [
        {
        "currency": "EUR",
        "value": 100
        },
        {
        "currency": "PLN",
        "value": 400
        }
    ],
  "description": "test desc"
}

JSON 回应

{
  "code": 400,
  "message": "Validation Failed",
  "errors": {
    "children": {
      "name": {},
      "description": {},
      "prices": {
        "errors": [
          "Not valid"
        ]
      }
    }
  }
}

问题特别在于价格 - 传递空价格数组会创建没有错误的产品。我使用 FOSRestBundle。

我用谷歌搜索了很多小时,但没有成功。我是 Symfony 的新手,所以我很可能错过了一些明显的东西:)

问题出在 ProductType class。

而不是:

$builder
->add('prices', EntityType::class, [
    'class' => Price::class,
    'multiple' => true,
    'constraints' => [
        new NotNull(),
    ],
]);

应该使用

$builder
->add('prices', CollectionType::class, [
    'entry_type' => PriceType::class,
    'allow_add' => true,
    'constraints' => [
        new NotNull(),
    ],
]);

已找到答案here