douliang2167 2013-09-24 17:25
浏览 36
已采纳

Symfony2,一对多关系,用自动新类别创建新任务

I'm trying to create new Task and this task assign to pre-created Categories. But problem is, after submit this form, it will automatically create a new category with the same name, which I selected in the category list, and then Symfony creates a new relation with them. I just want to assign a category id into Task object, no create a new Category. Here is Task object:

<?php

namespace Acme\TaskBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="tasks") 
 */
class Task
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;              

    /**
     * @ORM\Column(type="string", length=200)    
     * @Assert\NotBlank(
     *      message = "Task cannot be empty"      
     * )    
     * @Assert\Length(
     *      min = "3",
     *      minMessage = "Task is too short"         
     * )     
     */     
    protected $task;

    /**
     * @ORM\Column(type="datetime")    
     * @Assert\NotBlank()
     * @Assert\Type("\DateTime")
     */
    protected $dueDate;

    /**
     * @Assert\True(message = "You need to agree")    
     */         
    protected $accepted;

    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="tasks", cascade={"persist"})
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id")                        
     */
    protected $category;        

    public function getTask()
    {
        return $this->task;
    }

    public function setTask($task)
    {
        $this->task = $task;
    }

    public function getDueDate()
    {
        return $this->dueDate;
    }

    public function setDueDate(\DateTime $dueDate = null)
    {
        $this->dueDate = $dueDate;
    }

    public function getAccepted()
    {
        return $this->accepted;
    }

    public function setAccepted($accepted)
    {
        $this->accepted = (boolean) $accepted;
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set category
     *
     * @param \Acme\TaskBundle\Entity\Category $category
     * @return Task
     */
    public function setCategory(\Acme\TaskBundle\Entity\Category $category = null)
    {
        $this->category = $category;

        return $this;
    }

    /**
     * Get category
     *
     * @return \Acme\TaskBundle\Entity\Category 
     */
    public function getCategory()
    {
        return $this->category;
    }
}

Category object:

<?php

namespace Acme\TaskBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="categories") 
 */
class Category
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")        
     */
    protected $id; 

    /**
     * @ORM\Column(type="string", length=200)  
     * @Assert\NotNull(message="Please select a category", groups = {"adding"})                 
     */         
    protected $name;       

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Category
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

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

My DB TABLE Task:

ID | Task | dueDate | category_id (here is creating doctrine automatic foreign keys between task and category)

And DB TABLE Categories:

ID | Name
+-------------------+
1 | Main category
2 | Second category

And if I create a task, with the i.e. Main category, it will add a new Task into DB and add a new Category into DB with the name Main category. So result is:

Task table:
+----------------------------------------+
1 | My task name | 2013-09-27 00:00:00 | 3


Categories table:
+--------------------+
1 | Main category
2 | Second category
3 | Main category

Expected results:

Task table:
+----------------------------------------+
1 | My task name | 2013-09-27 00:00:00 | 1


Categories table:
+--------------------+
1 | Main category
2 | Second category

How can I fix it please?

UPDATE

TaskType form:

<?php

namespace Acme\TaskBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Acme\TaskBundle\Form\Type\Category;

class TaskType extends AbstractType
{
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\TaskBundle\Entity\Task',
            'cascade_validation' => true,
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('task', 'text', array('label' => 'Task'))
                ->add('dueDate', 'date', array('label' => 'Date'))
                ->add('category', new CategoryType(), array('validation_groups' => array('adding')))
                ->add('accepted', 'checkbox')
                ->add('save', 'submit', array('label' => 'Send'));
    }

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

CategoryType form:

<?php

namespace Acme\TaskBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class CategoryType extends AbstractType
{
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\TaskBundle\Entity\Category',
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', 'entity', array(
                  'class' => 'AcmeTaskBundle:Category',
                  'query_builder' => function($repository) { return $repository->createQueryBuilder('c')->orderBy('c.id', 'ASC'); },
                  'property' => 'name',
                  'empty_value' => 'Choose something',
                  ));
    }

    public function getName()
    {
        return 'category';
    }
}
  • 写回答

1条回答 默认 最新

  • dongxi2014 2013-09-25 14:30
    关注

    First of all you have to define unique the column "name" into category (ORM\Column) to avoid db inconsistence:

    class Category
    {
        [...]
    
        /**
         * @ORM\Column(type="string", length=200, unique=true)  
         * @Assert\NotNull(message="Please select a category", groups = {"adding"})                 
         */         
        protected $name;  
    

    Then to add a persistent category to your Task you have to find it and attach to your entity, so:

    // Find Category
    $category = $this->getDoctrine()->getManager()->getRepository('ACMETaskBundle:Category')->findByName("Category Name");
    
    // Add it to task
    $myTask->setCategory($category);
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料