如何使用 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"}
键 targets
有 TargetField
个 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;
}));
我正在使用 Symfony 和 FOSRestBundle
开发 RESTful 网络服务从前端我有一个表单,它创建字段并以以下格式发送到服务器:
{"targets":[1,3],"title":"This is a title","price":1200000,"description":"This is a description"}
键 targets
有 TargetField
个 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;
}));