我对 Symfony 2 框架相当陌生,因此由于对框架内部功能的理解不成熟而提出了一些新手问题。基本上,我有一个嵌入式表单,它是一对多的关系。我有一个名为 event 的实体,它至少有一个或多个时间对象
这是我的实体类
事件.php
<?php namespace KlikEvent\EventBundle\Entity; use Doctrine\ORM\Mapping as ORM;
> /**
> * @ORM\Entity
> * @ORM\Table(name="events")
> */
> class Event {
>
> /**
> * @ORM\Id
> * @ORM\Column(type="integer")
> * @ORM\GeneratedValue(strategy="AUTO")
> */
> protected $id;
>
> /**
> * @ORM\Column(type="string", length=50)
> */
> protected $eventTitle;
>
> ....
>
> /**
> * @ORM\OneToMany(targetEntity="Time", mappedBy="event", cascade={"all"})
> */
> protected $eventTimes;
>
> ......
>
> public function __construct() {
> $this->eventCategories = new \Doctrine\Common\Collections\ArrayCollection();
> $this->eventTimes = new \Doctrine\Common\Collections\ArrayCollection();
> }
>
> ...... setter + getter stuff ....
>
>
>
> /**
> * Add eventTimes
> *
> * @param KlikEvent\EventBundle\Entity\Time $eventTimes
> */
> public function addTime(\KlikEvent\EventBundle\Entity\Time $eventTimes)
> {
> $this->eventTimes[] = $eventTimes;
> }
>
> /**
> * Get eventTimes
> *
> * @return Doctrine\Common\Collections\Collection
> */
> public function getEventTimes()
> {
> return $this->eventTimes;
> }
>
> ......
>
> }
时间.php
<?php namespace KlikEvent\EventBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/** * @ORM\Entity * @ORM\Table(name="eventTime") */ class Time {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="Event", inversedBy="eventTimes")
* @ORM\JoinColumn(name="event_id", referencedColumnName="id")
*/
protected $event;
/**
* @ORM\Column(type="datetime")
*/
protected $begin;
/**
* @ORM\Column(type="datetime")
*/
protected $end;
...... setter + getter stuff
/**
* Set event
*
* @param KlikEvent\EventBundle\Entity\Event $event
*/
public function setEvent(\KlikEvent\EventBundle\Entity\Event $event)
{
$this->event = $event;
}
/**
* Get event
*
* @return KlikEvent\EventBundle\Entity\Event
*/
public function getEvent()
{
return $this->event;
}
}
现在,当我制作嵌入表单时,我扩展了 AbstractType 以制作可重用的表单类 ( http://symfony.com/doc/current/book/forms.html#creating-form-classes )
这是我的表单类
时间类型.php
<?php
namespace KlikEvent\EventBundle\Form;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilder;
class TimeType extends AbstractType {
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('begin')
->add('end')
;
}
public function getDefaultOptions ( array $options )
{
return array (
'data_class'=>'KlikEvent\EventBundle\Entity\Time',
);
}
public function getName()
{
return 'klikevent_eventbundle_timetype';
} }
和
EventType.php
<?php
namespace KlikEvent\EventBundle\Form;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilder;
use KlikEvent\EventBundle\Form\FeedbackType; use KlikEvent\EventBundle\Form\TimeType;
class EventType extends AbstractType {
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('feedback', new FeedbackType())
->add('eventTitle')
->add('eventLocation1')
->add('eventLocation2')
->add('eventShortDescription')
->add('eventDescription')
->add('eventFurtherDescription')
->add('eventCoverImage')
->add('eventImages')
->add('eventVideos')
->add('eventCategories')
->add('eventTimes', 'collection',
array ('type' => new TimeType(),
'allow_add' => true,
'prototype' => true,
'by_reference' => false
))
;
}
public function getName()
{
return 'klikevent_eventbundle_eventtype';
} }
现在,每当我想在 Controller 中处理输入的输入时,我都会调用 $form->bindRequest($request) 方法,但它会抛出一个错误,表明事件类中没有 setEventTimes () 方法
Property "eventTimes" is not public in class "KlikEvent\EventBundle\Entity\Event". Maybe you should create the method "setEventTimes()"?
这很奇怪,因为generate:doctrine:entities只生成addTimes方法而不是setEventTimes,我假设bindRequest方法的预期操作过程是将所有输入的时间对象添加到事件对象。我对这个错误感到困惑,很高兴获得帮助、指导,甚至提示我做错了什么
问候
编辑1..添加 Controller
Controller 在这里。我只显示相关的 Controller 方法,因为如果我显示所有内容就会太长
<?php
namespace KlikEvent\EventBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query\ResultSetMapping;
use KlikEvent\EventBundle\Entity\Subscriber;
use KlikEvent\EventBundle\Entity\Event;
use KlikEvent\EventBundle\Entity\Category;
use KlikEvent\EventBundle\Entity\Feedback;
use KlikEvent\EventBundle\Entity\Time;
use KlikEvent\EventBundle\Form\SubscribeType;
use KlikEvent\EventBundle\Form\FeedbackType;
use KlikEvent\EventBundle\Form\EventType;
use KlikEvent\EventBundle\Form\TimeType;
class DefaultController extends Controller<?php
namespace KlikEvent\EventBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query\ResultSetMapping;
use KlikEvent\EventBundle\Entity\Subscriber;
use KlikEvent\EventBundle\Entity\Event;
use KlikEvent\EventBundle\Entity\Category;
use KlikEvent\EventBundle\Entity\Feedback;
use KlikEvent\EventBundle\Entity\Time;
use KlikEvent\EventBundle\Form\SubscribeType;
use KlikEvent\EventBundle\Form\FeedbackType;
use KlikEvent\EventBundle\Form\EventType;
use KlikEvent\EventBundle\Form\TimeType;
class DefaultController extends Controller{
....
public function defaultTipsEventOwnerAction( Request $request )
{
$feedback_event_owner = new Event();
$time = new Time( );
$feedback_event_owner->addTime( $time );
$form_event_owner = $this->createForm(new EventType(), $feedback_event_owner);
if ($request->getMethod() == 'POST') {
$form_event_owner->bindRequest($request);
if ($form_event_owner->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($feedback_event_owner);
$em->flush();
$this->get('session')->setFlash('tips-notice-ok', 'Terima kasih untuk tips');
$feedback_event_owner = new Feedback();
$form_event_owner = $this->createForm(new FeedbackType(), $feedback_web);
return $this->render .....
);
}
else
{
$this->get('session')->setFlash('tips-notice-error', 'Maaf, Ada error. Coba lagi');
return $this->render .....
}
}
return $this->render .....
}
......
}
最佳答案
好的,经过几天的努力,我得到了这个。这是如此丑陋的黑客
基本上,generate:doctrine:entities 无法正确地为实体类生成适当的方法。这可能是也可能不是由于我的错误使用造成的,但在我的特定情况下,它没有正确创建 setEventTimes () 方法。
所以我所做的是,创建 setEventTimes () 方法,该方法基本上替换实体内的整个 eventTimes 集合
像这样
public function setEventTimes( $eventTimes )
{
$this->eventTimes = $eventTimes;
}
这与Symfony生成脚本生成的方法不同,后者本质上是一一添加Time实体
/** THIS IS GENERATED
* Add eventTimes
*
* @param KlikEvent\EventBundle\Entity\Time $eventTimes
*/
public function addTime(\KlikEvent\EventBundle\Entity\Time $eventTimes)
{
$this->eventTimes[] = $eventTimes;
}
这解决了 Symfony 2 之前向我抛出的错误。
经进一步检查,时间实体没有对事件实体的引用,在数据库中,时间的event_id列始终输入为NULL。因此,为了避免这种情况,我添加了一些代码,在将对象持久保存到数据库之前,在每次输入对象时添加对事件实体的引用,如下面的代码片段
foreach ( $feedback_event_owner->getEventTimes() as $times )
{
$times->setEvent($feedback_event_owner);
}
希望这可以帮助任何像我一样面临同样问题的人。
感谢@flukey 为帮助我所做的努力:D
关于Symfony 2表单bindRequest方法没有正确绑定(bind)一对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10381411/