ArrayCollection:在窗体中检索集合 [英] ArrayCollection: retrive collection in a form

查看:176
本文介绍了ArrayCollection:在窗体中检索集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用Symfony2制作了一个Web应用程序,其中一个用户与Mission实体有一个数组关联ManytoMany。用户可以通过表单上传实体$ product,并且表单传递的其中一个数据是与用户关联的任务。

每个用户不止有一项任务,所以,当他上传一个$ product对象时,他也应该能够选择他喜欢的任务。

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

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

它可以工作,但不是很好:事实上,在这个领域,我可以选择所有存储的任务,而不是只有与用户关联的那些。



我试过了:

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

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



我也试过:

   - > add(' ('required'=> true))

但它告诉我:

 属性任务和方法getMissions(),
isMissions ),hasMissions(),__get()存在并且在类Acme \ GlobeStoreBundle \Entity\Product中具有公共访问权限

我该如何更换控制器?

我的产品实体是:

  class产品
{
/ **
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ ORM\OneToMany(targetEntity =Acme\ManagementBundle\Entity\Mission,mappedBy =product )
* /
保护$任务;

// ...

/ **
*设置任务
*
* @param字符串$任务
* @返回产品
* /
公共功能setMission($ mission)
{
$ this-> mission = $ mission;

返回$ this;

$ b / **
*获取任务
*
* @return string
* /
public function getMission( )
{
return $ this-> mission;
}
// ...

更新---



我将发布我的产品和任务实体,如评论中所述

这是我的用户实体是:

 抽象类用户扩展BaseUser 
{
$ b $ / **
* @ var \Doctrine\Common\Collections\ArrayCollection
*
* @ ORM\ManyToMany(targetEntity =Acme\ManagementBundle\Entity\Mission,inversedBy =users, orphanRemoval = true)
* @ ORM\JoinTable(name =user_mission)
* /
private $ missions;
/ **
*增加任务
*
* @param \Acme\ManagementBundle\Entity\Mission $任务
* @返回用户
* /
public function addMission(\Acme\ManagementBundle\Entity\Mission $ missions)
{
$ this-> missions [] = $ missions;

返回$ this;
}
// ...

我的任务实体: p>

 <?php 

命名空间Acme \ManagementBundle \Entity;

使用Doctrine \ORM\Mapping作为ORM;
使用Doctrine\Common\Collections\ArrayCollection;
使用Doctrine\Common\Collections\Collection;

/ **
* @ ORM\Entity
* /
class Mission {
/ **
* @ ORM \ Id
* @ ORM\GeneratedValue
* @ ORM\Column(type =integer)
* @var整数
* /
保护$ id;
/ **
* @ ORM\Column(type =string,length = 60)
* @var String
* /
protected $ name;
/ **
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ ORM\ManyToOne(targetEntity =Acme\GroundStationBundle\\ );
* @ 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 =tasks,cascade = {all},orphanRemoval = true)
* /
private $ users;

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

$ b $ **
*获取id
*
* @return整数
* /
public function getId( )
{
return $ this-> id;

$ b / **
*名称
*
* @param字符串$名称
* @return Mission
* /
public function setName($ name)
{
$ this-> name = $ name;

返回$ this;

$ b / **
*获取名称
*
* @return字符串
* /
public function getName )
{
return $ this-> name;
}
$ b / **
*设置描述
*
* @param字符串$描述
* @return任务
* /
public function setDescription($ description)
{
$ this-> description = $ description;

返回$ this;

$ b / **
*获取描述
*
* @return string
* /
public function getDescription( )
{
return $ this-> description;
}

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

返回$ this;
}

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

/ **
*获取用户
*
* @return \Doctrine\Common\Collections\Collection
* /
public function getUsers()
{
return $ this-> users;
}
public function __toString()
{
return $ this-> name;
}
/ **
*设置产品
*
* @param \Acme\GroundStationBundle\Entity\Product $ product
* @return Mission
* /
公共功能setProduct(\Acme\GroundStationBundle\Entity\Product $ product = null)
{
$ this-> product = $产品;

返回$ this;
}

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


解决方案

看看我对代码的修改。



当你定义一个(产品)ToMany(任务)关系时,你有这样的情况:

1。产品具有许多任务,并且必须具有任务的ArrayCollection,您可以添加,移除或获取所有任务。

  class Product 
{
/ **
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ ORM \OneToMany(targetEntity =Acme \ManagementBundle\Entity\Mission,mappedBy =product)
* /
//将此属性重命名为复数。产品有许多任务
//比命名约定是人类可读的addMission和removeMission从收集但getMissions
保护$任务;
// ...

//
//删除这些函数:
public function setMission($ mission)
// ...
public function getMission()
// ...

//
//添加这些函数:
public function __construct(){
$ this-> missions = new ArrayCollection();
}

公共职能addMission(Acme \ManagementBundle\Entity\Mission $ mission)
{
$ this->任务[] = $任务;

返回$ this;
}

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

返回$ this;
}

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

2。强大>许多使命都属于一种产品。只更改注释

  class Mission {
// ...
// RENAME inversedBy to missions
/ **
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ ORM\ManyToOne(targetEntity =Acme\GroundStationBundle\ )
* @ 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;

// ...

//回滚这个函数:
public function setMission($ mission)
public function getMission()

//删除这些函数
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;

// ...

//
//删除这些函数:
public function setProduct($ product)
public function getProduct()
// ...

//
//添加这些函数:
public function __construct(){
$ this-> ; products = new ArrayCollection();
}

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

返回$ this;
}

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

返回$ this;
}

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

编辑结束

3。之后,请记住:

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

祝您好运!


I made a web application with Symfony2, in which a User has an array correlation ManytoMany with the entity Mission. The User can upload the entity $product through a form, and one of the data passed by the form is the mission associated to the user.

There are more than only one mission for every user; so, when he uploads a $product object, he should also be able to select the mission he prefers.

To upload the file I use a form in a controller in the following way:

       $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(); 

It works, but not fine: indeed in this field I can select all the mission stored, and not only the ones associated with the user.

I tried then with:

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

It works but shows only one mission, and doesn't allow the user to select the preferred mission.

I tried also with:

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

but it tells me:

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

How I should change my controller??

My product entity is:

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;
 }
//...

UPDATE ---

I will post also my product and mission entity, as asked in the comments

This is my User Entity is:

 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;
     }
//...

And my Mission Entity:

<?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;
}
}

解决方案

Please take a look at my changes to your code.

When you define One(product)ToMany(missions) relation you have situation like this:

1. Product has many missions and must have an ArrayCollection of missions which you can add, remove or get all.

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. Many MissionS are owned by one product. Change only annotation

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;

EDIT START

3. Opposite - MANY products Belongs to one Mission If there is situation like you mentioned in comment, then your Annotations are wrong. Look at this fix:

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;
}
//...

EDIT END

3. After that remember to:

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

Good Luck!

这篇关于ArrayCollection:在窗体中检索集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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