2014-01-30 3 views
1

Я создал веб-приложение с Symfony2, в котором у пользователя есть корреляция массива ManytoMany с сущностью Mission. Пользователь может загрузить продукт сущности $ через форму, а один из данных, передаваемых формой, - это миссия, связанная с пользователем.ArrayCollection: получение коллекции в виде

Для каждого пользователя существует более одной миссии; поэтому, когда он загружает объект $ 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; 
} 
//... 

UPDATE ---

Я вывешу также мой продукт и миссия организация, как просили в комментариях

Это мой Entity Пользователь является:

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

И моя миссия 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; 
} 
} 
+0

У вас есть необходимое свойство и геттеры в коде объекта? Продукт? –

+0

@whitelettersandblankspaces редактировали вопрос и помещали мой объект продукта. Должен ли я изменить аннотации? –

+2

миссия или миссии? Чтобы избежать таких вопросов, я использую командную строку для генерации моих объектов. –

ответ

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. Многие МИССИЯХ принадлежат одному продукту. Изменение только аннотации

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. противоположности - МНОГО продуктов Принадлежит к одной миссии Если есть ситуация, как вы упомянули в комментариях, то ваши Аннотации неверны. Посмотрите на это исправление:

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. После этого не забудьте:

$ 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!

+0

С -> add ('mission', 'collection') в контроллере я все еще не могу выбрать. :(На самом деле, каждый продукт принадлежит только одной миссии, но каждая миссия имеет много объектов. –

+0

Чем ваши аннотации все не так. Cuz ManyProductHasOneMission ... – WebHQ

+0

Тогда я попытаюсь все это изменить и дам вам знать. –

2

Говоря это:

Ни свойство "миссии", ни один из методов "getMissions()", "isMissions()", "hasMissions()", «__get() "существуют и имеют открытый доступ в классе " Acme \ GroundStationBundle \ Entity \ Product ".

Symfony2 говорит вам, что вы должны установить связь между Миссией и продуктом субъектов.

Попробуйте создать отношение 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 

Затем расскажите, что происходит в комментариях. Вам нужно будет провести какое-то тестирование, прежде чем заставить его работать, по моему мнению, но вы уже в пути;)

+0

Thats the thing. @GianniAlessandro взгляните на аннотации ORM User-> mission and Mission-> users ORM. Вы можете увидеть [примеры в доктрине doc] (http://docs.doctrine-project.org/en/latest/reference/association-mapping.html#one-to-many-bidirectional) для аннотаций «один ко многим». – WebHQ

+0

@ Jivan Я обновил аннотации (вы также можете увидеть это в вопросе) и обновил базу данных, но все же визуализируйте: Ни свойства «миссий», ни один из методов «getMissions()», «isMissions()», «hasMissions()», «__get()» существуют и имеют открытый доступ в классе «Acme \ GroundStationBundle \ Entity \ Product». –

+0

@WebHQ Я потерял время для глупой опечатки, но теперь аннотации должны быть в порядке. –

Смежные вопросы