使用symfony2 + doctrine + form更新db中的类对象的正确方法?

时间:2013-07-18 14:53:28

标签: forms class symfony doctrine updating

我有一个简单的课程:

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

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

    ... 
}

在数据库中有一些'type'对象。 所以,如果我想改变其中一个,我创建新的控制器规则(如/ types / edit / {id})和新动作:

public function typesEditViewAction($id)
{   
    ... 
    $editedType = new Type();

    $form = $this->createFormBuilder($editedType)
        ->add('name', 'text')
        ->add('id', 'hidden', array('data' => $id))
        ->getForm();

    // send form to twig template
    ...
}

之后,我创建另一个控制器规则(如/ types / do_edit)和操作:

public function typesEditAction(Request $request)
{   
    ... 
    $editedType = new Type();

    $form = $this->createFormBuilder($editedType)
        ->add('name', 'text')
        ->add('id', 'hidden')
        ->getForm();

    $form->bind($request); // <--- ERROR THERE !!!

    // change 'type' object in db
    ...
}

我在那里发现了一个小问题。 Сlass'Type'没有自动生成的setter setId(),并且在绑定时我得到了错误。

Neither the property "id" nor one of the methods "setId()", "__set()" or "__call()" exist and have public access in class "Lan\CsmBundle\Entity\Type".

现在,我从symfony2表单对象($ form)中删除'id'字段并将其手动传输到模板。 在第二个控制器的动作我有$ form对象和'id'-field分开。 我不知道这样做的“正确”方式(更新'type'类)。请帮忙。

2 个答案:

答案 0 :(得分:2)

Symfony有一个集成的ParamConverter,它会自动从数据库中提取您的实体并抛出异常(如果找不到该实体,则可以在侦听器中捕获)。

您可以在一个控制器方法中轻松处理GET和POST请求。

确保您的实体中有属性的公共getter和setter。

我添加了注释以使路由更清晰,并且仍然有一个工作示例。

use Vendor\YourBundle\Entity\Type;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

// ...

/** 
 *  @Route("/edit/{id}", requirements={"id" = "\d+"})
 *  @Method({"GET", "POST"})
 */
public function editAction(Request $request, Type $type)
{   

    $form = $this->createFormBuilder($type)
        ->add('name', 'text')
        ->add('id', 'hidden')
        ->getForm()
    ;

    if ($request->isMethod('POST')) {
         $form->bind($request);

         if ($form->isValid())
         {
              $em = $this->getDoctrine()->getEntityManager();
              $em->flush();          // entity is already persisted and managed by doctrine.

              // return success response
         }
    }

    // return the form ( will include the errors if validation failed )
}

我强烈建议你创建一个form type来进一步简化你的控制器。

答案 1 :(得分:1)

对于其他任何因为前端需要而将ID字段添加到FormType的地方,你可以将ID列设置为&#34; not-mapped&#34;像这样:

->add('my_field', 'hidden', ['mapped'=>false])

它可以防止尝试使用表单处理方法的ID值。