【问题标题】:Symfony2: ManyToMany relation and Collection form typeSymfony2:ManyToMany 关系和 Collection 表单类型
【发布时间】:2012-05-31 11:31:25
【问题描述】:

我在 Symfony2 项目中面临多对多关系的 Collection 表单类型的大问题。

环境: - Symfony 2.0.14 - 教义 2.1

这里有一些代码:

发布实体

class Post
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\Column(type="string", length=255, nullable=false)
 */
private $title;

/**
 * @ORM\ManyToMany(targetEntity="Tag", inversedBy="posts", cascade={"persist"})
 * @ORM\JoinTable(name="posts_tags")
 */
private $tags;

public function setTags(\Doctrine\Common\Collections\ArrayCollection $tags)
{
    foreach($tags as $tag)
    {
        $tag->addSnippet($this);
    }
}

public function addTag(\My\BlogBundle\Entity\Tag $tags)
{
    $this->tags[] = $tags;
}

public function getTags()
{
    return $this->tags;
}

标记实体

class Tag
{
/**
 * @var integer $id
 * 
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string $name
 * 
 * @ORM\Column(type="string", length=100, unique=true, nullable=false)
 */
private $name;

/**
 * @var Snippet
 * 
 * @ORM\ManyToMany(targetEntity="Post", mappedBy="tags") 
 */
private $posts;

public function addSnippet(\My\BlogBundle\Entity\Post $posts)
{
    $this->posts[] = $posts;
}

PostType 表单类

->add('tags', 'collection', array(
            'type' => new TagType(),
            'allow_add' => true,
            'prototype' => true,
            'by_reference' => false,
        ))

一切正常,但是在插入数据库SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'tag1' for key 'UNIQ_6FBC94265E237E06'中已经存在的标签时会引发错误。

您对此问题有任何解决方法还是我遗漏了什么?我的控制器是app/console.enter code here生成的标准CRUD控制器

【问题讨论】:

    标签: symfony doctrine-orm


    【解决方案1】:

    好吧,我对教义的处理不多,但似乎您在同一个集合中插入了一个具有相同 ID/名称的标签。我想你可以在插入之前检查标签是否存在

    public function existTags(\Doctrine\Common\Collections\ArrayCollection $tags)
    {
        foreach($this->tags as $tag)
        {
            if ( $tag->getID() === $tags->getId() )
                return true;
        }
        return false;
    }
    

    然后

    public function addTag(\My\BlogBundle\Entity\Tag $tags)
    {
        if ( !$this->existTag($tags) );
            $this->tags[] = $tags;
    }
    

    这些是我的模型:

    namespace models;
    
    
    /**
     * @Entity
     * @Table(name="tag")
     */
    class Tag
    {
    
        /**
         * @Id @Column(type="integer", nullable=false, name="id")
         * @GeneratedValue(strategy="AUTO")
         */
        protected $id;
    
    
        /**
         * @Column(type="string", nullable=false)
         */
        protected $name;
    
        public function getId(){ return $this->id; }
        public function getName(){ return $this->name; }
    
        public function setId($id){ $this->id = $id; }
        public function setName($name){ $this->name = $name; }
    
    
    }
    

    博客条目:

    namespace models;
    
    use \Doctrine\Common\Collections\ArrayCollection;
    
    /**
     * @Entity
     * @Table(name="entry")
     */
    class Entry
    {
    
        /**
         * @Id @Column(type="integer", nullable=false, name="id")
         * @GeneratedValue(strategy="AUTO")
         */
        protected $id;
    
        /**
         * @Column(type="string", nullable=false, name="body")
         */
        protected $body;
    
    
    
        /**
         * @ManyToMany(targetEntity="Tag")
         * @JoinTable(name="entry_tagged",
         *      joinColumns={@JoinColumn(name="entry_id", referencedColumnName="id")},
         *      inverseJoinColumns={@JoinColumn(name="tag_id", referencedColumnName="id")}
         *      )
         */
        private $tags;
    
    
    
    
    
        public function __construct(){
            $this->tags = new ArrayCollection();
        }
    
        public function existTag(models\Tag $tag)
        {
            foreach($this->tags as $temp)
            {
                if ( $tag->getID() === $temp->getId() )
                    return true;
            }
            return false;
        }
    
        public function addTag(models\Tag $tag)
        {
            if ( !$this->existTag($tag) );
                $this->tags->add($tag);
        }
    
    
        public function getId(){ return $this->id; }
        public function getBody(){ return $this->body; }
        public function getTags(){ return $this->tags; }
    
        public function setId($id){ $this->id = $id; }
        public function setBody($body){ $this->body = $body; }
        public function setTags($tags){ $this->tags = $tags; }
    
    }
    

    最后,使用的连接表是“entry_tagged”,如下所示:

    entry_id | tag_id
    

    【讨论】:

    • 它似乎试图插入另一个同名标签 - 这就是为什么它对我来说有点奇怪。
    • 是的,因此您需要检查要插入的新 tah 是否已经存在于 $tags 集合中,就像上面的方法一样
    • 我已经把它放在 Post 实体中 - 仍然是同样的错误。我错过了什么吗?
    • 您可以编辑帖子以查看所有标签和帖子实体属性吗?
    • 好吧,我已经复制了你的模型并且它已经工作了,但是在 posts_tags 表中我已经包含了另一列 auto_increment 作为主键。而且效果很好
    猜你喜欢
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    相关资源
    最近更新 更多