【问题标题】:Sonata admin don't save the many-to-many fieldSonata 管理员不保存多对多字段
【发布时间】:2014-02-27 11:14:01
【问题描述】:

这是常见的问题。 有许多复选框的表格。使复选框可用并点击保存,对应复选框标签的字段不保存。

PersonAdmin 类包含

        ...
       ->add('books', 'sonata_type_model', 
                array('by_reference' => false, 'expanded' => true, 'multiple' => true, 'label' => 'Books'))
       ...

实体类包含

     /**
      * @ORM\ManyToMany(targetEntity="Book", mappedBy="persons", cascade={"persist"})
      * @ORM\JoinTable(name="person_book")
      */
    protected $books;

    ....

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

    public function addBook(Book $book)
    {
        $this->books[] = $book;

        return $this;
    }

还有 geters、seters...

我没有成功地寻找解决方案。我发现有必要添加

               'by_reference' => false, 

或

                cascade={"persist"}

但我的代码中包含所有这些。

【问题讨论】:

    标签: forms symfony many-to-many sonata-admin


    【解决方案1】:

    如前所述,您需要保存双方的关系。但我更喜欢另一种方式:在实体的添加操作中保存关系:

    //In the Person entity:
    public function addBook(Book $book)
    {
        $book->addPerson($this);
        $this->books[] = $book;
    
        return $this;
    }
    
    //In the Book entity (if you have the same problem for another side):
    public function addPerson(Person $person)
    {
        $person->addBook($this);
        $this->persons[] = $person;
    
        return $this;
    }
    

    【讨论】:

    • 这段代码导致无限递归 addPerson → addBook → addPerson ... 我将$book->addPerson($this);嵌套在​​if ($book->hasPerson($this) === true)中
    【解决方案2】:

    你必须在两边都保存。

    覆盖自定义 crud 控制器中的默认 editAction 和 createAction。

    例如:

    这是艺术家和活动之间多对多关系的一个例子。

    ($object 是您在动作中编辑/创建的当前对象)

    foreach ($form['selectArtists']->getData() as $key => $value) {
                    $artist = $em->getRepository('MyCompanyProjectBundle:Artist')->findOneById($value);
                    $object->addArtist($artist);
                    $artist->addEvent($object);
                    $em->persist($artist);
                }
    

    【讨论】:

    • 您也可以在实体中执行此操作。在 addArtist 方法中,您对作为参数发送的艺术家对象执行 addEvent。如果出现问题,您应该在 addBook 方法中添加 $book->addPerson($this)
    【解决方案3】:

    使用edit=>内联。

       ->add('books', 'sonata_type_collection', 
                array('by_reference' => false, 'label' => 'Books'),
                array('edit'=>'inline','inline'=>'table'))
    

    可能对你有帮助。

    【讨论】:

      猜你喜欢
      • 2015-12-17
      • 2011-12-24
      • 1970-01-01
      • 2011-06-26
      • 2012-08-23
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      • 2012-08-27
      相关资源
      最近更新 更多