无法使用填充的Entity对象设置表单获取表单的视图数据应该是标量,数组或\ ArrayAccess实例的类型

时间:2013-09-11 20:47:43

标签: symfony symfony-forms symfony-2.3

我创建了EntityClass:

<?php

namespace Rota\Bundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\component\OptionsResolver\OptionsResolverIntrerface;
use Doctrine\Common\Collections\ArrayCollection;

/**
* RotaObj
*
* @ORM\Table()
* @ORM\Entity
*/
class RotaMain
{
   public function __construct()
 {
     $this->rotaShifts = new ArrayCollection();
 }

/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var integer
 *
 * @ORM\Column(name="MyUserId", type="integer")
 */
private $myUserId;

/**
 * @var date
 * 
 * @ORM\Column(name="RotaStartDate", type="date")
 */
private $startDate;

/**
 * @var date
 * 
 * @ORM\Column(name="RotaReviewDate", type="date")
 */
private $reviewDate;

/**
 * @var integer
 * 
 * @ORM\Column(name="RotaRollingWeeks", type="integer")
 */
 private $rollingWeeks;

 /**
  * @var integer
  * 
  * @ORM\Column(name="restDayCount", type="integer")
  */
 private $restDayCount;

 /**
  * @var integer
  * 
  * @ORM\Column(name="totalDayCount", type="integer")
  */
 private $totalDayCount;


 /**
  * @ORM\OneToMany(targetEntity="RotaShift",mappedBy="rotaMain",cascade={"persist"})
  */
 protected $rotaShifts;

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

/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set myUserId
 *
 * @param integer $myUserId
 * @return RotaObj
 */
public function setMyUserId($myUserId)
{
    $this->myUserId = $myUserId;

    return $this;
}

/**
 * Get myUserId
 *
 * @return integer 
 */
public function getMyUserId()
{
    return $this->myUserId;
}

/**
 * Set startDate
 *
 * @param \DateTime $startDate
 * @return RotaObj
 */
public function setStartDate($startDate)
{
    $this->startDate = $startDate;

    return $this;
}

/**
 * Get startDate
 *
 * @return \DateTime 
 */
public function getStartDate()
{
    return $this->startDate;
}

/**
 * Set reviewDate
 *
 * @param \DateTime $reviewDate
 * @return RotaObj
 */
public function setReviewDate($reviewDate)
{
    $this->reviewDate = $reviewDate;

    return $this;
}

/**
 * Get reviewDate
 *
 * @return \DateTime 
 */
public function getReviewDate()
{
    return $this->reviewDate;
}

/**
 * Set rollingWeeks
 *
 * @param integer $rollingWeeks
 * @return RotaObj
 */
public function setRollingWeeks($rollingWeeks)
{
    $this->rollingWeeks = $rollingWeeks;

    return $this;
}

/**
 * Get rollingWeeks
 *
 * @return integer 
 */
public function getRollingWeeks()
{
    return $this->rollingWeeks;
}

/**
 * Add rotaShifts
 *
 * @param \Rota\Bundle\Entity\RotaShift $rotaShifts
 * @return RotaMain
 */
public function addRotaShift(\Rota\Bundle\Entity\RotaShift $rotaShift)
{
    $this->rotaShifts[] = $rotaShift;

    return $this;
}

/**
 * Remove rotaShifts
 *
 * @param \Rota\Bundle\Entity\RotaShift $rotaShifts
 */
public function removeRotaShift(\Rota\Bundle\Entity\RotaShift $rotaShifts)
{
    $this->rotaShifts->removeElement($rotaShifts);
}

/**
 * Get rotaShifts
 *
 * @return \Doctrine\Common\Collections\Collection 
 */
public function getRotaShifts()
{
    return $this->rotaShifts;
}



/**
 * Set restDayCount
 *
 * @param integer $restDayCount
 * @return RotaMain
 */
public function setRestDayCount($restDayCount)
{
    $this->restDayCount = $restDayCount;

    return $this;
}

/**
 * Get restDayCount
 *
 * @return integer 
 */
public function getRestDayCount()
{
    return $this->restDayCount;
}

/**
 * Set totalDayCount
 *
 * @param integer $totalDayCount
 * @return RotaMain
 */
public function setTotalDayCount($totalDayCount)
{
    $this->totalDayCount = $totalDayCount;

    return $this;
}

/**
 * Get totalDayCount
 *
 * @return integer 
 */
public function getTotalDayCount()
{
    return $this->totalDayCount;
}



/**
 * Set shiftOrder
 *
 * @param string $shiftOrder
 * @return RotaMain
 */
public function setShiftOrder($shiftOrder)
{
    $this->shiftOrder = $shiftOrder;

    return $this;
}

/**
 * Get shiftOrder
 *
 * @return string 
 */
public function getShiftOrder()
{
    return $this->shiftOrder;
}
}

此类包含以下集合:

<?php

namespace Rota\Bundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* RotaShift
* 
* @ORM\Table()
* @ORM\Entity
*/
class RotaShift
{
/**
 * @var integer
 * 
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $_id;

/**
 * @var integer
 * 
 * @ORM\Column(name="startTime", type="integer")
 */
private $_startTime;

/**
 * @var integer
 * 
 * @ORM\Column(name="endTime", type="integer")
 */
private $endTime;

/**
 * @var string
 * 
 * @ORM\Column(name="name", type="string", length=50)
 */
private $name;


/**
 * @ORM\ManyToOne(targetEntity="RotaMain", inversedBy="rotaShifts")
 */
private $rotaMain;


/**
 * Get _id
 *
 * @return integer 
 */
public function getId()
{
    return $this->_id;
}

/**
 * Set _startTime
 *
 * @param integer $startTime
 * @return RotaShift
 */
public function setStartTime($startTime)
{
    $this->_startTime = $startTime;

    return $this;
}

/**
 * Get _startTime
 *
 * @return integer 
 */
public function getStartTime()
{
    return $this->_startTime;
}

/**
 * Set endTime
 *
 * @param integer $endTime
 * @return RotaShift
 */
public function setEndTime($endTime)
{
    $this->endTime = $endTime;

    return $this;
}

/**
 * Get endTime
 *
 * @return integer 
 */
public function getEndTime()
{
    return $this->endTime;
}

/**
 * Set name
 *
 * @param string $name
 * @return RotaShift
 */
public function setName($name)
{
    $this->name = $name;

    return $this;
}

/**
 * Get name
 *
 * @return string 
 */
public function getName()
{
    return $this->name;
}

/**
 * Set rotaMain
 *
 * @param \Rota\Bundle\Entity\RotaMain $rotaMain
 * @return RotaShift
 */
public function setRotaMain(\Rota\Bundle\Entity\RotaMain $rotaMain = null)
{
    $this->rotaMain = $rotaMain;

    return $this;
}

/**
 * Get rotaMain
 *
 * @return \Rota\Bundle\Entity\RotaMain 
 */
public function getRotaMain()
{
    return $this->rotaMain;
}
}

然后我为RotaMain对象创建了一个Form EntityType类,如下所示:

<?php

namespace Rota\Bundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class RotaMainType extends AbstractType
{
   public function buildForm(FormBuilderInterface $builder, array $options)
   {
    $builder->  add('ReviewDate','date');
    $builder->add('RollingWeeks','integer');
    $builder->add('StartDate','date');
    $builder->add('RestDayCount','integer',array('label' => 'Number of rest days'));
    $builder->add('TotalDayCount','integer',array('label' => 'Total number of days in     shift pattern'));
    $builder->add('rotaShifts','collection',array('type'=> new RotaShiftType(),'label' => false,'allow_add' => true,));
    $builder->add('Save','submit');
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
     $resolver->setDefaults(array(
    'data_class' => 'Rota\Bundle\Entity\RotaMain',
));
}


public function getName()
{
    return 'rotaMain';
}
}

当我尝试使用完全填充的RotaMain对象设置表单时:

$form = $this->createForm(new RotaMainType(),$RotaMain);

我收到以下错误:

  

表单的视图数据应该是标量,数组或实例的类型   \ ArrayAccess,但是是Rota \ Bundle \ Entity \ RotaMain类的实例。你可以避免   将“data_class”选项设置为“Rota \ Bundle \ Entity \ RotaMain”或通过   添加一个转换类实例的视图转换器   Rota \ Bundle \ Entity \ RotaMain为标量,数组或\ ArrayAccess的实例。

我在RotaMainType对象中设置了data_class,所以不确定我哪里出错?如果我将一个空的RotaMain对象传递给它按预期构建的表单。

RotaMain的数量发生在控制器中。表格是两部分过程的第一部分。如果用户已完成第一部分消失并回来,我想在进入过程的第二部分之前重新审视他们的第一部分。控制器动作:

public function setRotaAction(Request $request,$userId)
{
    //Check to see if user has part set up a rota - return completed form for review
     $RotaMainRepos = $this->getDoctrine()->getManager()->getRepository("RotaBundle:RotaMain");
     $id = $this->getUser()->getID();
     $criteria = array("myUserId"=>$id);
     $result = $RotaMainRepos->findBy($criteria);
     if($result == null)
     {
       $RotaMain = new RotaMain();
       $RotaMain->setmyUserId($userId);
       $form = $this->createForm(new RotaMainType(),$RotaMain);
     }
     else
     {
        $RotaMain = $result[0];
        $rotashiftRepo = $this->getDoctrine()->getManager()->getRepository("RotaBundle:RotaShift");
        $rotaShifts = $rotashiftRepo->findByRotaMain($RotaMain);
        foreach($rotaShifts as $rotaShift)
        {
            $RotaMain->addRotaShift($rotaShift);
        }
        $form = $this->createForm(new RotaMainType(),$RotaMain);

     }


     $form->handleRequest($request);

     if($form->isValid())
     {
        $early = $form->getData();
        $em = $this->getDoctrine()->getManager();
        $em->persist($early);

        $shifts = $early->getRotaShifts();
        foreach($shifts as $shift)
        {
         $shift->setRotaMain($early);
         $em->persist($shift);
        }
        $em->flush();
        $shiftOrder = new ShiftOrder($shifts,$early->getRestDayCount(),$early->getTotalDayCount());
        return $this->render("RotaBundle:Default:shiftOrder.html.twig",array("shiftOrder" => $shiftOrder));
     }

     return $this->render('RotaBundle:Default:setRota.html.twig',array("form" => $form->createView(),));




}

2 个答案:

答案 0 :(得分:1)

您必须将与配置的data_class相同类型的新创建或现有实体/对象绑定到表单。

如果您没有将您传递给表单的变量设置为预期data_class symfony的对象,则不会创建该对象,但会抛出此异常。

在您的情况下,您可能希望使用SensioFrameworkExtraBundle的@ParamConverter从数据库中获取实体并清理控制器。

/**
 * @Route("/whatever/{id}")
 * @ParamConverter("rotaMain", class="RotaBundle:RotaMain", options={"mapping": {"MyUserId": "id"}})
 */
public function editAction(RotaMain $rotaMain, Request $request)
{

    $form = $this->createForm(new RotaMainType(), $rotaMain);       
    $form->handleRequest($request);
    if ($form->isValid()) {
        //  
    }
}

......或......

public function newAction(Request $request)
{

    $form = $this->createForm(new RotaMainType(), $rotaMain = new RotaMain());       
    $form->handleRequest($request);
    if ($form->isValid()) {
        //  
    }
}

答案 1 :(得分:0)

找到了答案 - 这是我在RotaMain中访问和设置MyRotaShift实体的方式。我的addRotashift()函数没有正确地将rotaShifts添加到Doctrine ArrayColleciton。将我的控制器代码更改为:

 foreach($rotaShifts as $rotaShift)
 {
    $RotaMain->getRotaShifts()->add($rotaShift);
 }

一切正常。以为我疯了一会儿!

结果并没有发疯,但我应该在推进前阅读Doctrine文档。如果我有,我会意识到这是使用延迟加载并为自己节省了一大堆麻烦!!!

接受了nifr的答案,因为它提供了一个很好的方式来完成我想要完成的事情