doulu1945 2016-06-28 15:32
浏览 54
已采纳

Symfony 3.x - 对提交的表单数据对象使用实体getId()方法返回对象(不是整数)

I am trying to create a filter form with multiple fields, and one of them is a select/drop-down for selecting from a list of Tournaments.

The idea is to make the form reusable so I'm creating a FilterType form class. The Tournament select field is created by embedding a TournamentChoiceType form class which creates an EntityType field using the Tournament entity.

The issue I'm facing is when the form is submitted and I get the submitted data. The $tournamentChoice is a Tournament object (which is OK), but $tournamentId = $tournamentChoice->getId() is returning a Tournament object too, and it should be an integer (the ID columnn).

The mess seems to happen here:

$filterForm->handleRequest($request);

because when I view/dump the raw POST request all seems normal and the filter[tournament][id] is just an integer parameter passed in, as expected.

Here's the code.

Controller:

$em = $this->getDoctrine()->getManager();
$tournamentSelected = $em->getRepository('MyBundle:Tournament')
        -> findOneById($id);
$tournamentsList = $em->getRepository('MyBundle:Tournament')
        ->findAll();

$formInputData = array();
$formInputData['tournament']['data'] = $tournamentSelected;
$formInputData['tournament']['choices'] = $tournamentsList;
formData = array();

$filterForm = $this->createForm(FilterType::class, $formData, array(
    'data' => $formInputData
));

$filterForm->handleRequest($request);

if ($filterForm->isSubmitted() && $filterForm->isValid()) {
    $formData = $filterForm->getData();

    $tournamentChoice = $formData['tournament'];
    $tournamentId = $tournamentChoice->getId();
    $dateFromChoice = $formData['date_from'];
    $dateToChoice = $formData['date_to'];

    return $this->redirectToRoute(
        'index',
        array('tournament' => $tournamentId)
    );
}

FilterType form class:

class FilterType extends AbstractType
{
    protected $data;

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => null
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $this->data = $options['data'];

        ...

        $builder
            ->add('tournament', TournamentChoiceType::class, array(
                'choices' => $this->data['tournament']['choices'],
                'data' => $this->data['tournament']['data']
            ))
        ;

        ...
    }
}

TournamentChoiceType form class:

class TournamentChoiceType extends AbstractType
{
    protected $data;
    protected $choices;

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'MyBundle\Entity\Tournament',
            'choices' => null
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $this->data = $options['data'];
        $this->choices = $options['choices'];

        $builder
            ->add('id', EntityType::class, array(
                'class' => 'MyBundle:Tournament',
                'choices' => $this->choices,
                'choice_label' => 'name',
                'label' => false,
                'data' => $this->data
            ))
        ;
    }
}

Tournament entity class:

class Tournament
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    ...

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

    ...
}

Here's how var_dump($filterForm->getData()) looks like, after a submit:

array (size=4)
  'field1' => string 'text' (length=4)
  'field2' => string 'text' (length=4)
  ...
  'tournament' => 
    object(MyBundle\Entity\Tournament)[631]
      private 'id' => 
        object(MyBundle\Entity\Tournament)[522]
          private 'id' => int 11
          private 'name' => string 'tournament1' (length=11)
          private ...
          ...

and here's how var_dump($filterForm->getData()) looks like, after a second submit:

array (size=4)
  'field1' => string 'text' (length=4)
  'field2' => string 'text' (length=4)
  ...
  'tournament' => 
    object(MyBundle\Entity\Tournament)[513]
      private 'id' => 
        &object(MyBundle\Entity\Tournament)[513]
      private 'name' => string 'tournament1' (length=11)
      private ...

What's with the object's ID being an object (and not being just an interger), or referencing an object?

  • 写回答

2条回答 默认 最新

  • doukuanjing5404 2016-06-30 15:18
    关注

    The problem is caused by double data insertion. You have to refactor your code to set the data only once.

    Firstly you set it here:

    $formInputData['tournament']['data'] = $tournamentSelected;

    Secondly if there is any request, then you set it again here:

    $filterForm->handleRequest($request);

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 博通raid 的写入速度很高也很低
  • ¥15 目标计数模型训练过程中的问题
  • ¥100 Acess连接SQL 数据库后 不能用中文筛选
  • ¥15 用友U9Cloud的webapi
  • ¥20 电脑拓展屏桌面被莫名遮挡
  • ¥20 ensp,用局域网解决
  • ¥15 Python语言实验
  • ¥15 我每周要在投影仪优酷上自动连续播放112场电影,我每一周遥控操作一次投影仪,并使得电影永远不重复播放,请问怎样操作好呢?有那么多电影看吗?
  • ¥20 电脑重启停留在grub界面,引导出错需修复
  • ¥15 matlab透明图叠加