Doctrine 2: в поле формы в качестве значения указывается Doctrine\Common\Collections\ArrayCollection@00

Я довольно новичок в Zend Framework 2 и Doctrine 2, поэтому я даже не уверен, как искать или отлаживать мою проблему.

У меня есть 3 таблицы базы данных

1. реклама
Я бы
рекламный заголовок...

2. категория
Я бы
имя категории...

3. объявление_категория
advert_id
category_id

Я создал 2 сущности, рекламу и категорию. Теперь у меня есть форма, в которой я показываю категории на выбор. Я использую jQuery для отображения категорий в виде списка вместо выпадающего списка вместе с выбираемой функцией. Поэтому, когда вы нажимаете на категорию, значение этого списка вводится в скрытое поле ввода, называемое категориями.

Все работает отлично, кроме того, что когда я отображаю форму, поле ввода скрытых категорий получило значение Doctrine\Common\Collections\ArrayCollection@000000000..... вместо того, чтобы быть пустым. Что я здесь не так делаю? Я пытался найти решение, но безуспешно.

Я выбрал ManyToMany Relationship, потому что хочу сохранить в итоге более 1 категории. В настоящее время он работает только с 1, но таким образом я смогу изменить это позже.

Вот мой рекламный объект:

namespace Advert\Entity;

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

/** Advert
 * 
 * @ORM\Table(name="advert")
 * @ORM\Entity(repositoryClass="Advert\Repository\AdvertRepository")
 */

class Advert
{
 /**
  * @var integer
  *
  * @ORM\Column(name="id", type="integer", nullable=false)
  * @ORM\Id
  * @ORM\GeneratedValue(strategy="IDENTITY")
  */
  private $id;


 /**
  * @var string
  *
  * @ORM\Column(name="advert_title", type="string", length=255, nullable=true)
  */
  private $advertTitle; 

 /** 
  * @ORM\ManyToMany(targetEntity="Category", inversedBy="adverts", cascade={"persist"}) 
  * @ORM\JoinTable(name="advert2category") 
  */
  private $categories;

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

 /**
  * Set categories
  *
  * @param ArrayCollection $category
  * @return Advert
  */
  public function setCategories($categories)
  {
    $this->categories = $categories;
    return $this;
  }


 /**
  * Get categories
  *
  * @return ArrayCollection
  */
  public function getCategories()
  {
    return $this->categories;
  }

  /**
   * @param Collection $categories
   */
  public function addCategories($categories)
  {
    foreach ($categories as $category) {
        $this->categories->add($category);
    }
  }

  /**
   * @param Collection $categories
   */
  public function removeCategories($categories)
  {
    foreach($categories as $category){
        $this->categories->removeElement($category);
    }

  }

Есть ли ошибка в рекламном объекте, которая вызывает это? Я надеюсь, что кто-то может помочь. У меня есть проблемы с неделями, и я не могу заставить его работать правильно.

ОБНОВЛЕНИЕ - добавлена ​​моя форма и часть в контроллере для вызова формы

В приведенной ниже форме отображаются 2 выпадающих элемента и 2 скрытых поля ввода. 2 выпадающих поля превращаются в выбираемый список с помощью jQuery. Когда вы щелкаете элемент списка в главной категории, подкатегории снова отображаются для выбранной основной категории в качестве списка выбора. Затем MaincategoryID вводится в скрытое поле categoryID. Как только вы выбираете подкатегорию из списка, идентификатор этой категории записывается в поле скрытых категорий. Нажатие на кнопку "Далее" сохраняет значение $_POST['category'] вместе с advertID в моей таблице ссылок.

use Zend\Form\Form;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;

class CategoryForm extends Form implements ObjectManagerAwareInterface
{

protected $objectManager;


public function __construct()
{       
    $this->setInputFilter(new AdvertFilter());
    parent::__construct('category');


}

public function init()
{
    $this->setAttribute('method', 'post');




    $this->add(array(
            'name' => 'categories',
            'attributes' => array(
                    'type' => 'hidden',
                    'id'    => 'categories',

            ),
            'options'=> array(
                    'label'=> 'categories',
                    ),


    ));


    $this->add(
            array(

                    'type' => 'DoctrineModule\Form\Element\ObjectSelect',
                    'name' => 'categoriesList',

                    'options' => array(

                            'object_manager' => $this->getObjectManager(),
                            'label' => 'Main Category',
                            'target_class'   => 'Advert\Entity\Category',
                            'property'       => 'name',
                            'is_method' => true,

                            'find_method'        => array(
                                    'name'   => 'getMainCategories',
                            ),
                    ),
                    'allow_empty'  => true,
                    'required'     => false,
                    'attributes' => array(
                            'id' => 'categoryList',
                            'multiple' => true,


                    )
            )
    );

    $this->add(
            array(
                    'type' => 'DoctrineModule\Form\Element\ObjectSelect',
                    'name' => 'subcategoryList',
                    'options' => array(
                            'object_manager' => $this->getObjectManager(),
                            'label' => 'Sub Category',


                            'target_class'   => 'Advert\Entity\Category',
                            'property'       => 'name',

                            'is_method' => true,
                            'find_method'        => array(
                                    'name'   => 'getSubCategories',
                            ),
                    ),
                    'allow_empty'  => true,
                    'required'     => false,
                    'attributes' => array(

                            'id' => 'subcategoryList',
                            'multiple' => true,
                            )
            )
    );


    $this->add(array(
            'type' => 'hidden',
            'name' => 'categoryID',
            'options'=> array(
                    'label'=> 'categoryID'),
            'attributes' => array(
                    'id' => 'categoryID',
                    'value' => '1',
            )
    ));

   $this->add(array(
            'name' => 'submit',
            'attributes' => array(
                    'type'  => 'submit',
                    'value' => 'Next',
                    'id' => 'submitbutton',
            ),
    ));



}

public function setObjectManager(ObjectManager $objectManager)
{
    $this->objectManager = $objectManager;
}

public function getObjectManager()
{
    return $this->objectManager;
}

}

В моем контроллере я называю свою форму следующим образом:

    $sl = $this->getServiceLocator();
    $form = $sl->get('FormElementManager')->get('\Advert\Form\CreateForm');

    # create a new, empty entity
    $advert = new Advert();

    # set the hydrator to connect form and entity
    $form->setHydrator(new DoctrineHydrator($this->getEntityManager(),'Advert\Entity\Advert'));

    # connect form and entity
    $form->bind($advert);

1 ответ

Во-первых, двунаправленные отношения не используют таблицы соединений. Ваше отображение выглядит двунаправленным, однако вы пытаетесь использовать третью таблицу: advert_category,

Я рекомендую изменить отображение $categories собственностью Advert сущность к однонаправленным отношениям:

class Advert
{
     // ...

    /**
     * @ORM\ManyToMany(targetEntity="Category")
     * @ORM\JoinTable(name="advert_category",
     *      joinColumns={@ORM\JoinColumn(name="advert_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")}
     *      )
     **/
    protected $categories;

    // ...
}

Также вы должны реализовать addCategories(Collection $categories) а также removeCategories(Collection $categories) методы внутри Advert сущность, если вы хотите воспользоваться гидратором DoctrineObject. (Я предполагаю, что вы используете DoctrineORMModule).

На данный момент ваш Category сущность не должна ничего знать о Advert и вы не можете напрямую получить доступ ко всем объявлениям из экземпляра категории с помощью метода объекта, например $category->getAdverts(), Однако при необходимости вы можете легко написать getAdvertsByCategoryId($categoryId) метод в вашем AdvertRepository.

Последняя деталь, вы должны иметь CategoryFieldset (который также должен использовать Category сущность как объект), и вы должны указать этот набор полей в форме categories использование элемента target_elementКонфигурационный ключ или непосредственно предоставление самого экземпляра.

Например:

$formManager = $serviceLocator->get('FormElementManager');
$form = $formManager->get('your\form\name');
$form->add(
    array(
        'name' => 'categories',
        'type' => 'Zend\Form\Element\Collection',
        'options' => array(
            'target_element' => $formManager->get('your\fieldset\name');
            // or you can do this but probably you will also need $entityManager
            // inside the CategoryFieldset
            // 'target_element' => new CategoryFieldset();
            ),
        )
    );

Я настоятельно рекомендую использовать FormElementManager чтобы получить экземпляры формы и набора полей непосредственно для их создания new AdvertForm() а также new CategoryFieldset(), Также пишу AbstractFormElementFactory было бы хорошей практикой для инъекций $entityManager как зависимости от ваших наборов полей и форм, правильный путь.

Надеюсь, поможет.

Другие вопросы по тегам