duanchen9594 2015-03-22 01:53
浏览 41
已采纳

Symfony PUT不包含映射的所有实体属性

I am using FOSRestBundle to manage the API in my app. So I got almost everything working, except PUT method, where some of the properties are NULL but they shouldn't since the entity (id 105) has them filled in.

Take a look at the putAction:

    /**
     * @ParamConverter("user", class="SoftwareBundle:User", options={"mapping": {"user": "guid"}})
     */
    public function putAction(Request $request, $user)
    {
        $form = $this->createForm(new UserType(), $user, ['method' => 'PUT']);
        $form->handleRequest($request);

        var_dump($user->getId()); // 105
        var_dump($user->getGuid()); // 12345
        var_dump($user->getEmailAddress()); // NULL (should be johndoe@example.com
        var_dump($user->getFirstName()); // NULL (should be John)
        var_dump($user->getLastName()); // NULL (should be Doe)
        var_dump($user->getSex()); // NULL (should be 0)
        var_dump($user->getPassword()); // pass123
        var_dump($user->getUserAgent()); // curl/7.30.0
        var_dump($user->getIpAddress()); // 127.0.0.1
        var_dump($user->getMember()->getPrivateNotes()); // example note

        if($form->isValid())
        {
            $manager = $this->getDoctrine()->getManager();
            $manager->flush();

            return $this->view([
                'user' => $user
            ]);
        }

        return $this->view($form, Codes::HTTP_BAD_REQUEST);
    }

Question is, why FirstName, LastName, EmailAddress and Sex are NULL? They really shouldn't.

Here is how the form looks like:

class UserType extends AbstractFormType
{
    public function buildForm(FormBuilderInterface $builder, array $option)
    {
        $builder
            ->add('firstName', 'text', [
                'label' => 'word.first_name',
                'required' => true
            ])
            ->add('lastName', 'text', [
                'label' => 'word.last_name',
                'required' => true
            ])
            ->add('emailAddress', 'email', [
                'label' => 'word.email_address',
                'required' => true,
                'constraints' => [
                    new HasUsername($this->getOption('uuid'))
                ]
            ])
            ->add('sex', 'choice', [
                'label' => 'word.sex',
                'choices' => [
                    '0' => 'word.male',
                    '1' => 'word.female'
                ],
                'required'    => true,
                'empty_value' => 'word.select',
                'empty_data' => null
            ])
            ->add('locale', 'entity', [
                'label' => 'word.locale',
                'required'    => false,
                'property' => 'code',
                'class' => 'SoftwareBundle:Locale',
                'query_builder' => function(EntityRepository $er) {
                        return $er->createQueryBuilder('l')
                            ->orderBy('l.code', 'ASC');
                    },
                'placeholder' => 'word.select',
                'empty_data'  => null
            ])
            ->add('member', new MemberType(), [])
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults([
            'translation_domain'    => 'general',
            'data_class'            => 'Software\Bundle\Entity\User',
            'attr'                  => ['novalidate' => 'novalidate'],
            'csrf_protection'       => false
        ]);
    }

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

Validation is done in a separate .yml file.

This is the JSON I am sending to put action:

{"user":{"member": {"privateNotes":"example note"}}}"

Any ideas?

  • 写回答

1条回答 默认 最新

  • drsb77336 2015-03-22 09:19
    关注

    I've solved it in past with event listeners. The trick is to rewrite the value for defaults if submitted value is null:

    namespace Acme\Bundle\UserBundle\Form;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormEvents;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\Form\FormEvent;
    
    class UserType extends AbstractType
    {
        /**
         * @param FormBuilder $builder
         * @param array       $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('email')
                ->add('name');
    
            $callback = function(FormEvent $event) {
                if (null === $event->getData()) {
                    $event->setData($event->getForm()->getData());
                }
            };
    
            $builder->get('email')->addEventListener(FormEvents::PRE_SUBMIT, $callback);
            $builder->get('name')->addEventListener(FormEvents::PRE_SUBMIT, $callback);
        }
    
       // [ ... ]
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求帮我调试一下freefem代码
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图