ArrayCollection:检索表单中的集合

时间:2014-01-30 01:38:42

标签: php forms symfony arraycollection

我使用Symfony2创建了一个Web应用程序,其中User具有与实体Mission相关的数组关联ManytoMany。用户可以通过表单上传实体$产品,表单传递的数据之一是与用户关联的任务。

每个用户只有一个任务;因此,当他上传$ product对象时,他也应该能够选择他喜欢的任务。

要上传文件,我按照以下方式在控制器中使用表单:

       $form = $this->createFormBuilder($product)
           ->add('mission', 'entity', array('required' => true, 'multiple' => false, 'class' => 'AcmeManagementBundle:Mission', 'query_builder' => function($repository) { return $repository->createQueryBuilder('c')->orderBy('c.id', 'ASC'); },))              
      //...
           ->add('save', 'submit')
           ->getForm(); 

它有效,但不是很好:确实在这个领域我可以选择存储的所有任务,而不仅仅是与用户相关的任务。

然后我尝试了:

       $form = $this->createFormBuilder($product)
           ->add('mission', 'collection', array('required' => true) )
      //...
           ->add('save', 'submit')
           ->getForm(); 

它可以工作但只显示一个任务,并且不允许用户选择首选任务。

我也尝试过:

           ->add('mission', 'collection', array('required' => true) )

但它告诉我:

Neither the property "missions" nor one of the methods "getMissions()", 
"isMissions()", "hasMissions()", "__get()" exist and have public access 
in class "Acme\GroundStationBundle\Entity\Product".

我应该如何更改我的控制器?

我的产品实体是:

class Product
{
/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 * 
 * @ORM\OneToMany(targetEntity="Acme\ManagementBundle\Entity\Mission", mappedBy="product")
 */
 protected $mission;

//...

 /**
  * Set mission
  *
  * @param string $mission
  * @return Product
  */
 public function setMission($mission)
 {
     $this->mission = $mission;

     return $this;
 }

 /**
  * Get mission
  *
  * @return string 
  */
 public function getMission()
 {
     return $this->mission;
 }
//...

更新---

我还会在评论中提到我的产品和使命实体

这是我的用户实体:

 abstract class User extends BaseUser
 {

      /**
      * @var \Doctrine\Common\Collections\ArrayCollection
      * 
      * @ORM\ManyToMany(targetEntity="Acme\ManagementBundle\Entity\Mission", inversedBy="users", orphanRemoval=true)
      * @ORM\JoinTable(name="user_mission")
      */
     private $missions;    
     /**
      * Add missions
      *
      * @param \Acme\ManagementBundle\Entity\Mission $missions
      * @return User
      */
     public function addMission(\Acme\ManagementBundle\Entity\Mission $missions)
     {
         $this->missions[] = $missions;

         return $this;
     }
//...

我的使命实体:

<?php

namespace Acme\ManagementBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

/**
 * @ORM\Entity
 */
class Mission {
    /** 
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     * @var integer
     */
    protected $id;
        /** 
     * @ORM\Column(type="string", length=60)
     * @var String
     */
    protected $name;
/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 * 
 * @ORM\ManyToOne(targetEntity="Acme\GroundStationBundle\Entity\Product", inversedBy="mission")
 * @ORM\JoinColumn(name="productId", referencedColumnName= "id")
 */ 
private $product;
    /** 
     * @ORM\Column(type="string", length=600)
     * @var String
     */
    protected $description;
    /**
     * @var \Doctrine\Common\Collections\ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="Acme\ManagementBundle\Entity\User", mappedBy="missions", cascade={"all"}, orphanRemoval=true)
     */
    private $users;

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

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

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

        return $this;
    }

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

    /**
     * Set description
     *
     * @param string $description
     * @return Mission
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

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

    /**
     * Add users
     *
     * @param \Acme\ManagementBundle\Entity\User $users
     * @return Mission
     */
    public function addUser(\Acme\ManagementBundle\Entity\User $users)
    {
        $this->users[] = $users;

        return $this;
    }

    /**
     * Remove users
     *
     * @param \Acme\ManagementBundle\Entity\User $users
     */
    public function removeUser(\Acme\ManagementBundle\Entity\User $users)
    {
        $this->users->removeElement($users);
    }

    /**
     * Get users
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getUsers()
    {
        return $this->users;
    }
    public function __toString()
    {
        return $this->name;
    }
/**
 * Set product
 *
 * @param \Acme\GroundStationBundle\Entity\Product $product
 * @return Mission
 */
public function setProduct(\Acme\GroundStationBundle\Entity\Product $product = null)
{
    $this->product = $product;

    return $this;
}

/**
 * Get product
 *
 * @return \Acme\GroundStationBundle\Entity\Product 
 */
public function getProduct()
{
    return $this->product;
}
}

2 个答案:

答案 0 :(得分:2)

说这个:

  

财产“任务”和其中一种方法都没有   “getMissions()”,“isMissions()”,“hasMissions()”,“__ get()”存在并且   在课堂上有公共访问权限   “Acme公司\ GroundStationBundle \实体\产品”。

Symfony2告诉您您必须在Mission和Product 实体之间设置关系。

尝试通过在对象中设置注释和属性来创建这些实体之间的oneToMany / manyToOne关系。我对注释不够熟练,但我能说出它在Yaml中会是什么样子:

# in Product:
oneToMany:
    missions:
        targetEntity: Mission
        mappedBy: product

# in Mission:
manyToOne:
    product:
        targetEntity: Product
        inversedBy: missions
        joinColumn:
            name: productId
            referencedColumnName: id

在测试之前,不要忘记将对象更新为注释:

$ php app/console doctrine:generate:entities YourBundle:Product
$ php app/console doctrine:generate:entities YourBundle:Mission

然后,告诉我们评论中会发生什么。在我认为你工作之前,你将不得不做一些测试,但是你正在路上;)

答案 1 :(得分:2)

请查看我对您的代码所做的更改。

当您定义One(产品)ToMany(任务)关系时,您会遇到以下情况:

1。产品有许多任务,必须有一个任务的ArrayCollection,你可以添加,删除或获取所有任务。

class Product
{
/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 * 
 * @ORM\OneToMany(targetEntity="Acme\ManagementBundle\Entity\Mission", mappedBy="product")
 */
// RENAME this attribute to plural. Product HAS MANY missions
// Than naming convention is "human readable" addMission and removeMission from collection but getMissions
protected $missions;
//...

//
// remove those functions:
public function setMission($mission)
//...
public function getMission()
//...

//
// add those functions:
public function __construct(){
        $this->missions = new ArrayCollection();
    }

public function addMission( Acme\ManagementBundle\Entity\Mission $mission )
{
    $this->missions[] = $mission;

    return $this;
}

public function removeMission( Acme\ManagementBundle\Entity\Mission $mission )
{
    $this->missions->removeElement( $mission );

    return $this;
}

public function getMissions()
{
    return $this->missions;
}
//...

2. 许多MissionS归一个产品所有。仅更改注释

class Mission {
//... 
// RENAME inversedBy to missions
/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 * 
 * @ORM\ManyToOne(targetEntity="Acme\GroundStationBundle\Entity\Product", inversedBy="missions")
 * @ORM\JoinColumn(name="productId", referencedColumnName= "id")
 */ 
private $product;

编辑开始

3。对面 - 许多产品属于一个任务 如果您在评论中提到的情况,那么您的注释是错误的。看看这个修复:

class Product
{
// ...
/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 * 
 * @ORM\ManyToOne(targetEntity="Acme\GroundStationBundle\Entity\Mission", inversedBy="products")
 * @ORM\JoinColumn(name="missionId", referencedColumnName= "id")
 */
protected $mission;

// ...

// roll back this functions:
public function setMission($mission)
public function getMission()

// remove those functions
public function __construct(){
public function addMission( Acme\ManagementBundle\Entity\Mission $mission )
public function removeMission( Acme\ManagementBundle\Entity\Mission $mission )
public function getMissions()
//...



class Mission {
// ...
/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 * 
 * @ORM\OneToMany(targetEntity="Acme\ManagementBundle\Entity\Product", mappedBy="mission")
 */ 
private $products;

// ...

//
// remove those functions:
public function setProduct($product)
public function getProduct()
//...

//
// add those functions:
public function __construct(){
        $this->products = new ArrayCollection();
    }

public function addProduct( Acme\ManagementBundle\Entity\Product $product )
{
    $this->products[] = $product;

    return $this;
}

public function removeProduct( Acme\ManagementBundle\Entity\Product $product )
{
    $this->products->removeElement( $product );

    return $this;
}

public function geProducts()
{
    return $this->products;
}
//...

编辑结束

3. 之后请记住:

$ php app/console doctrine:generate:entities AcmeGroundStationBundle:Product
$ php app/console doctrine:generate:entities AcmeGroundStationBundle:Mission
$ php app/console doctrine:schema:update --force

祝你好运!