【问题标题】:One to many inserting on wrong table一对多插入错误的表
【发布时间】:2019-05-17 13:28:08
【问题描述】:

我有一个关系,其中有一个名为“Category”的表和另一个名为“Beer”的表,当我尝试使用 api 给我的类别创建新啤酒时一个错误。

啤酒控制器

/**
 * @Route("/", methods={"POST"})
 * @param  Request $request
 * @return Response
 */
public function saveAction(Request $request){

    $data_arr = json_decode($data = $request->getContent(),true);
    $beer = new Beer();
    $category = new Category();

    $beer->getCategory();
    $form = $this->createForm(BeerType::class, $beer);
    $form->submit($data_arr);

    $beer->setCategory($category);
    $doctrine = $this->getDoctrine()->getManager();
    $doctrine->persist($category);
    $doctrine->merge($beer);
    $doctrine->flush();
    return new JsonResponse([$data_arr], 200);
}

BeerEntity

/**
 * Beer
 *
 * @ORM\Table(name="beers")
 * @ORM\Entity
 */
class Beer
{

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category", inversedBy="beer", cascade={"persist", "remove" }))
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
     */
    private $category;

    /**
     * @return mixed
     */
    public function getCategory()
    {
        return $this->category;
    }

    /**
     * @param mixed $category
     */
    public function setCategory($category)
    {
        $this->category = $category;
    }

}

类别实体

class Category
{
    /**
     * @ORM\OneToMany(targetEntity="AppBundle\Entity\Beer", mappedBy="category")
     */
    private $beer;

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

BeerType(form)

class BeerType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array 
    $options)
    {
        $builder->add('name')
            ->add('description')
            ->add('price')
            ->add('slug')
            ->add('type')
            ->add('abv')
            ->add('brewedby')
            ->add('createdat')
            ->add('updatedat')
            ->add('category', EntityType::class, [
                    'class' => Category::class
                ]) 
   ;

console.log(error)

"执行'INSERT INTO category (name)时发生异常 VALUES (?)' 带参数 [null]" SQLSTATE [23000]:违反完整性约束:1048 列“名称” 不能为空”

正如问题本身所说,当我尝试创建具有类别(已创建)的新啤酒时,控制器尝试创建新类别,但我想创建已创建类别的新啤酒。

编辑:

当我通过 api 从 beer 发送数据时,category 发送正常,但是当我尝试使用 get 推送 beer 时,category 不再是 beers。

后啤酒

{abv: 7, brewedby: "Péttrin Miranda Souza", category_id: "7", description: "Descrição da cerva",…}
abv: 7
brewedby: "Péttrin Miranda Souza"
category_id: "7"
description: "Descrição da cerva"
name: "Beer"
price: "25"
slug: "mugger"
type: "Cerveja bavaria"

喝啤酒

5: {id: 19, name: "Beer", description: "Descrição da cerva", price: 25, slug: "mugger",…}
abv: 7
brewedby: "Péttrin Miranda Souza"
createdat: "2019-05-20T09:28:08-03:00"
description: "Descrição da cerva"
id: 19
name: "Beer"
price: 25
slug: "mugger"
type: "Cerveja bavaria"
updatedat: "2019-05-20T09:28:08-03:00"

【问题讨论】:

  • 阅读错误信息,然后问问自己类别名称是在哪里设置的。提示:不是。
  • 现在多注意听上去好像我很傻xD。

标签: api symfony


【解决方案1】:

由于您已经在表单中选择了类别实体,因此无需在您的操作中实例化类别实体或将其持久化(遇到的错误来自创建新实例并将其持久化 - 而不是使用现有类别连接到表单数据绑定中的啤酒实体的引用)。您可以尝试以下操作版本:

/**
 * @Route("/", methods={"POST"})
 * @param  Request $request
 * @return Response
 */
public function saveAction(Request $request){

    $doctrine = $this->getDoctrine()->getManager();

    $data_arr = json_decode($data = $request->getContent(),true);
    $beer = new Beer();

    $form = $this->createForm(BeerType::class, $beer);
    $form->submit($data_arr);

    $category = $doctrine->getRepository(Category::class)->find($data_arr['category_id']);
    $beer->setCategory($category);

    $doctrine->persist($beer);
    $doctrine->flush();

    return new JsonResponse([$data_arr], 200);
}

在附加 cmets 之后更新了答案。因此,现在根据给定的参数 id 显式获取类别。另一种解决方案 - 之前的简单控制器代码没有任何特殊的类别获取 - 将使用表单数据转换器 (symfony data transormer),它会自动将 int id 映射到类别对象。

【讨论】:

  • 有效,但未在申请中发送类别。
  • “请购单”是什么意思?它没有存储到数据库 id 字段中 - 或者没有通过响应发回?还是别的什么?
  • 来自Api的申请,类别是从api正常发送的,我会编辑我的问题,看看你是否明白。
  • 好的,我相应地更新了答案。基本上为此,您有两个选择:在操作中显式获取类别(如更新的答案中所做的那样)或创建一个数据转换器到表单,该表单将自动将 id 映射到实体(在这种情况下,表单提交将进行实体连接,因此控制器代码不需要处理类别实体)。
  • Hnmm,我想我明白了,前端开发人员很难,工作很好你的答案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 2012-02-20
  • 1970-01-01
  • 2012-10-23
  • 1970-01-01
  • 2021-11-29
  • 2020-02-09
相关资源
最近更新 更多