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
как зависимости от ваших наборов полей и форм, правильный путь.
Надеюсь, поможет.