由于1-n的唯一性约束,无法持久 [英] Unable to persist because of uniqueness constraints for 1-n

查看:67
本文介绍了由于1-n的唯一性约束,无法持久的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我让用户以单一形式而不是两种不同形式来保存品牌汽车数据对于出现在 Brands 表中的那些品牌,错误消息 品牌已存在于数据库中 。它应该如何工作:如果品牌名称已经存在,那么不要尝试再次保留它,因为名称字段在数据库中被标记为唯一。我该如何解决这个问题?

I let users persist Brands and Cars data in a single form instead of having two different forms however I'm getting an error message "The Brand already exist in database." for those brands which already exist in Brands table. How it should work is: if the brand name already exists then don't try to persist it again because name field is marked as unique in database. How can I solve this issue?

注意:之所以要使用两种额外的表单类型,是因为我还需要收集两种不同的界面品牌和汽车数据。

Note: The reason why I have two extra form types is because I also have two different interfaces to collect brands and cars data individually.

控制器

public function createAction(Request $request)
{
    if ($request->getMethod() != 'POST')
    {
        return new Response('Only POST method is allowed');
    }

    $form = return $this->createForm(new BothType(), null,
            array('action' => $this->generateUrl('bothCreate')));

    $form->handleRequest($request);

    if ($form->isValid())
    {
        $brandsData = $form->get('brands')->getData();
        $carsData = $form->get('cars')->getData();

        $brands = new Brands();
        $brands->setName($brandsData->getName());

        $cars = new Cars();
        $cars->setModel($carsData->getModel());
        $cars->setBrands($brands);

        $em = $this->getDoctrine()->getManager();
        $em->persist($brands);
        $em->persist($cars);
        $em->flush();

        return $this->redirect($this->generateUrl('both'));
    }

    return $this->render('CarBrandBundle:Default:both.html.twig',
            array('page' => 'Both', 'form' => $form->createView()));
}

两种类型

class BothType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->setMethod('POST')
            ->setAction($options['action'])
            ->add('brands', new BrandsType())
            ->add('cars', new CarsType())
            ->add('button', 'submit', array('label' => 'Add'))
            ;
    }
} 

品牌实体

/**
 * @ORM\Entity
 * @ORM\Table(name="brands", uniqueConstraints={@ORM\UniqueConstraint(columns={"name"})})
 * @UniqueEntity(fields="name", message="The Brand already exist in database.")
 * @package Car\BrandBundle\Entity
 */
class Brands
{
    protected $id;
    protected $name;

    /**
     * @ORM\OneToMany(targetEntity="Cars", mappedBy="brands")
     */
    protected $cars;

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

    public function getId() { return $this->id; }
    public function setName($name) { $this->name = $name; return $this; }
    public function getName() { return $this->name; }

    public function addCar(\Car\BrandBundle\Entity\Cars $cars)
    {
        $this->cars[] = $cars;
        return $this;
    }

    public function removeCar(\Car\BrandBundle\Entity\Cars $cars)
    {
        $this->cars->removeElement($cars);
    }

    public function getCars()
    {
        return $this->cars;
    }
}

品牌类型

class BrandsType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->setAction($options['action'])
            ->setMethod('POST')
            ->add('name', 'text', array('label' => 'Name'))
            ->add('button', 'submit', array('label' => 'Add'))
        ;
    }
}

汽车实体

class Cars
{
    protected $id;
    protected $model;

    /**
     * @ORM\ManyToOne(targetEntity="Brands", inversedBy="cars")
     * @ORM\JoinColumn(name="brands_id", referencedColumnName="id", nullable=false)
     */
    protected $brands;

    public function getId() { return $this->id; }
    public function setModel($model) { $this->model = $model; return $this; }
    public function getModel() { return $this->model; }

    public function setBrands(\Car\BrandBundle\Entity\Brands $brands = null)
    {
        $this->brands = $brands;
        return $this;
    }

    public function getBrands()
    {
        return $this->brands;
    }
}

汽车类型

class CarsType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->setAction($options['action'])
            ->setMethod('POST')
            ->add('model', 'text', array('label' => 'Model'))
            ->add('price', 'text', array('label' => 'Price'))
            ->add('button', 'submit', array('label' => 'Add'))
        ;
    }
} 


推荐答案

已解决通过使用未映射到数据库的表单模型,以便我可以忽略导致整个问题的唯一性检查。

Solved by using form model which is not mapped to database so that I could ignore uniqueness check which was causing the whole problem.

1。没有映射到数据库的名为BothModel的新模型:

1. Create a new Model called BothModel which is not mapped to database:

class BothModel
{
    /**
     * @Assert\NotBlank(message="The Name field should not be blank")
     */
    protected $name;

    /**
     * @Assert\NotNull(message="The Origin field should not be blank")
     */
    protected $origin;

    /**
     * @Assert\NotNull(message="The Model field should not be blank")
     */
    protected $model;

    /**
     * @Assert\NotNull(message="The Price field should not be blank")
     */
    protected $price;


    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setOrigin($origin)
    {
        $this->origin = $origin;
        return $this;
    }

    public function getOrigin()
    {
        return $this->origin;
    }

    public function setModel($model)
    {
        $this->model = $model;
        return $this;
    }

    public function getModel()
    {
        return $this->model;
    }

    public function setPrice($price)
    {
        $this->price = $price;
        return $this;
    }

    public function getPrice()
    {
        return $this->price;
    }
} 

2。更新BothType并单独添加表单字段,而不是启动Brands和Cars表单类型。

2. Update BothType and add form fields individually rather than initiating Brands and Cars form types.

class BothType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->setMethod('POST')
            ->setAction($options['action'])
            ->add('name', 'text', array('label' => 'Name'))
            ->add('origin', 'text', array('label' => 'Origin'))
            ->add('model', 'text', array('label' => 'Model'))
            ->add('price', 'text', array('label' => 'Price'))
            ->add('button', 'submit', array('label' => 'Add'))
            ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array('data_class' => 'Car\BrandBundle\Form\Model\BothModel'));
    }

    public function getName()
    {
        return 'both';
    }
} 

3。相应的控制器:

public function createAction(Request $request)
{
    if ($request->getMethod() != 'POST')
    {
        return new Response('Only POST method is allowed');
    }

    $form = $this->createForm(new BothType(), new BothModel(),
            array('action' => $this->generateUrl('bothCreate')));

    $form->handleRequest($request);

    if ($form->isValid())
    {
        $submission = $form->getData();

        $repo = $this->getDoctrine()->getRepository('CarBrandBundle:Brands');
        $brands = $repo->findOneBy(array('name' => $submission->getName()));

        if (! $brands)
        {
            $brands = new Brands();
            $brands->setName($submission->getName());
            $brands->setOrigin($submission->getOrigin());
        }

        $cars = new Cars();
        $cars->setModel($submission->getModel());
        $cars->setPrice($submission->getPrice());
        $cars->setBrands($brands);

        $em = $this->getDoctrine()->getManager();
        $em->persist($brands);
        $em->persist($cars);
        $em->flush();

        //return new Response('Brands ID: ' . $brands->getId() . ' - Cars ID: ' . $cars->getId());

        return $this->redirect($this->generateUrl('both'));
    }

    return $this->render('CarBrandBundle:Default:both.html.twig',
            array('page' => 'Both', 'form' => $form->createView()));
}

这篇关于由于1-n的唯一性约束,无法持久的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆