如何使用 FormType 和多对多关系与 FOSRestBundle

How to use FormType and ManyToMany relationships with FOSRestBuendle

我正在使用 Symfony 和 FOSRestBundle

开发 RESTful 网络服务

从前端我有一个表单,它创建字段并以以下格式发送到服务器:

{"targets":[1,3],"title":"This is a title","price":1200000,"description":"This is a description"}

targetsTargetField 个 ID。使用下面的代码,我得到一个状态码为 500 的响应,表示 foreach 参数无效(参见 FieldType->buildForm()

字段

/**
 * @ORM\Table(name="field")
 * @ORM\Entity
 */
class Field extends Property {

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

    /**
     * @ORM\ManyToMany(targetEntity="FieldTarget")
     * @ORM\JoinTable(name="relFieldTarget",
     *      joinColumns={@ORM\JoinColumn(name="fieldId", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="fieldTargetId", referencedColumnName="id")}
     *      )
     * */
    private $targets;

    public function __construct() {
        $this->targets = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public function getTargets() {
        return $this->targets;
    }
}

字段目标

/**
 * @ORM\Table(name="fieldTarget")
 * @ORM\Entity
 */
class FieldTarget
{

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

    /**
     * @var string
     * @ORM\Column(name="title", type="string")
     **/
    private $title
}

字段类型

class FieldType extends PropertyType {

    private $manager;

    function __construct(ObjectManager $manager){
        $this->manager = $manager;
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)     {
        parent::buildForm($builder, $options);
        $builder
            ->add('targets');

        $builder
            ->get('targets')
            ->addModelTransformer(new CallbackTransformer(
                    function($fieldTargetIds) {  // $fieldTargetIds is empty. WHY!?
                        $fieldTargetRepo = $this->manager->getRepository('FooBundle:FieldTarget');

                        foreach($fieldTargetIds as $id){
                            $fieldTarget[] = $fieldTargetRepo->find($id);
                        }

                        return $fieldTargets; // Here I'm tried hardcoding array($fieldTargetRepo->find(1)) and the field is created but is not related with the fieldTarget 1
                    }, 
                    function() {

                    }));
}

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'Cboujon\PropertyBundle\Entity\Field'
        ));
    }

}

现场控制器

/**
 * Create a Field entity.
 *
 * @View(statusCode=201, serializerEnableMaxDepthChecks=true)
 *
 * @param Request $request
 *
 * @return Response
 *
 */
public function postAction(Request $request) {
    $entity = new Field();
    $form = $this->createForm(new FieldType($this->getDoctrine()->getManager()), $entity, array("method" => $request->getMethod()));
    $this->removeExtraFields($request, $form);
    $form->handleRequest($request);

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

        return $entity;
    }

    return FOSView::create(array('errors' => $form->getErrors()), Codes::HTTP_INTERNAL_SERVER_ERROR);
}

您将代码放在了错误的函数中。回调转换器中的第一个函数从模型转换为视图,第二个函数从视图转换为模型。在这种情况下,您正在尝试为第二个操作添加代码。将您的代码更改为:

        ->addModelTransformer(new CallbackTransformer(
                function($fieldTargets) { 
                    //TODO: code to transform from the model into the view
                }, 
                function($fieldTargetIds) {
                    $fieldTargetRepo = $this->manager->getRepository('FooBundle:FieldTarget');

                    foreach($fieldTargetIds as $id){
                        $fieldTarget[] = $fieldTargetRepo->find($id);
                    }

                    return $fieldTargets; 
                }));