如何使用与FOSRestBuendle的FormType和ManyToMany关系

时间:2015-10-19 13:12:43

标签: php symfony fosrestbundle

我正在使用带有FOSRestBundle的Symfony开发RESTful Web服务

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

{"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;
    }
}

FieldTarget

/**
 * @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
}

的FieldType

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'
        ));
    }

}

FieldController

/**
 * 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);
}

1 个答案:

答案 0 :(得分:0)

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

        ->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; 
                }));