我有一个问题,我认为可能是相当基本的,但原因是逃避我。
我有两个实体,一个组织和一个订阅。一个组织与一个订阅链接在一起。
我想能够编辑这通过一个表单(创建通过表单已经工作)。当我执行以下操作时:
$organisation = $this->getDoctrine()->getRepository('AppBundle'Entity'Organisation')
->findOneBy(array(
'id' => $id
));
$form = $this->createForm(new OrganisationType(), $organisation, array(
'method' => 'POST'
));
$form->submit($paramFetcher->all());
我得到一个异常,因为没有设置组织实体的订阅属性(尽管将具有订阅的属性传递到表单默认值中)。例外情况如下:
Expected argument of type "AppBundle'Entity'Subscription", "NULL" given
这显然是由组织实体上的setSubscription方法抛出的,但我不确定为什么表单应该自动转换传递给订阅实体的int值。
我做了什么蠢事吗?我将相关代码附在下面。谢谢你!
复制这个问题的最简单的控制器动作
public function testAction(Request $request)
{
$organisation = $this->getDoctrine()->getRepository('AppBundle'Entity'Organisation')
->findOneBy(array('id' => 7));
$form = $this->createForm(new OrganisationType(), $organisation);
$form->submit($request->request->all());
return $this->render('test.html.twig', array(
'testform' => $form->createView()
));
}
Organisation.php
<?php
namespace AppBundle'Entity;
use Doctrine'Common'Collections'Collection;
use Doctrine'ORM'Mapping as ORM;
use JMS'Serializer'Annotation as JMS;
use Gedmo'Mapping'Annotation as Gedmo;
use Symfony'Component'Validator'Constraints as Assert;
/**
* Organisation
*
* @ORM'Table(name="organisation")
* @ORM'Entity(repositoryClass="AppBundle'Repository'OrganisationRepository")
*/
class Organisation
{
const ENABLED = 1;
const DISABLED = 2;
/**
* @var int
*
* @ORM'Column(name="id", type="integer")
* @ORM'Id
* @ORM'GeneratedValue(strategy="AUTO")
* @JMS'Groups({"default", "list-organisation"})
*/
private $id;
/**
* @var string
*
* @ORM'Column(name="name", type="string", length=255)
* @JMS'Groups({"default", "list-organisation"})
*/
private $name;
/**
* @var Subscription|null The subscription this organisation is currently linked to
* @ORM'ManyToOne(targetEntity="Subscription", inversedBy="organisations")
* @ORM'JoinColumn(name="subscription_id", referencedColumnName="id", onDelete="set null")
* @JMS'Groups({"default", "list-organisation"})
*/
private $subscription;
/**
* @var Collection
* @ORM'OneToMany(targetEntity="User", mappedBy="organisation")
* @JMS'Groups({})
*/
private $users;
/**
* @var Collection
* @ORM'OneToMany(targetEntity="Subgroup", mappedBy="organisation")
* @JMS'Groups({"default"})
*/
private $subgroups;
/**
* @var string $enabled
*
* @ORM'Column(type="string")
*/
private $enabled = self::ENABLED;
/**
* @var datetime $created
*
* @Gedmo'Timestampable(on="create")
* @ORM'Column(type="datetime")
* @JMS'Groups({"default", "list-organisation"})
*/
private $created;
/**
* @var datetime $updated
*
* @Gedmo'Timestampable(on="update")
* @ORM'Column(type="datetime")
* @JMS'Groups({"default", "list-organisation"})
*/
private $updated;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Organisation
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Sets subscription
*
* @param Subscription $subscription
* @return $this
*/
public function setSubscription(Subscription $subscription)
{
$this->subscription = $subscription;
return $this;
}
/**
* Gets subscription
*
* @return Subscription|null
*/
public function getSubscription()
{
return $this->subscription;
}
/**
* Sets enabled
*
* @param $enabled
*/
public function setEnabled($enabled)
{
if (!in_array($enabled, array(self::ENABLED, self::DISABLED))) {
throw new 'InvalidArgumentException('Invalid enabled status');
}
$this->enabled = $enabled;
}
/**
* Gets enabled
*
* @return string
*/
public function getEnabled()
{
return $this->enabled;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Returns Users belonging to this organisation
*
* @return Collection
*/
public function getUsers()
{
return $this->users;
}
public function __toString()
{
return $this->getName();
}
}
Subscription.php
<?php
namespace AppBundle'Entity;
use Doctrine'Common'Collections'Collection;
use Doctrine'ORM'Mapping as ORM;
use JMS'Serializer'Annotation as JMS;
use Gedmo'Mapping'Annotation as Gedmo;
/**
* Organisation
*
* @ORM'Table(name="subscription")
* @ORM'Entity(repositoryClass="AppBundle'Repository'SubscriptionRepository")
*/
class Subscription
{
/**
* @var int
*
* @ORM'Column(name="id", type="integer")
* @ORM'Id
* @ORM'GeneratedValue(strategy="AUTO")
* @JMS'Groups({"default", "list-organisation"})
*/
private $id;
/**
* @var string
*
* @ORM'Column(name="name", type="string", length=255)
* @JMS'Groups({"default", "list-organisation"})
*/
private $name;
/**
* @var Collection
* @ORM'OneToMany(targetEntity="Organisation", mappedBy="subscription")
* @JMS'Groups({"default"})
*/
private $organisations;
/**
* @var datetime $created
*
* @Gedmo'Timestampable(on="create")
* @ORM'Column(type="datetime")
* @JMS'Groups({"default"})
*/
private $created;
/**
* @var datetime $updated
*
* @Gedmo'Timestampable(on="update")
* @ORM'Column(type="datetime")
* @JMS'Groups({"default"})
*/
private $updated;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Subscription
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Returns Organisations with this subscription type
*
* @return Collection
*/
public function getOrganisations()
{
return $this->organisations;
}
/**
* @return string
*/
public function __toString()
{
return $this->getName();
}
}
OrganisationType.php
<?php
namespace AppBundle'Form;
use Doctrine'Common'Persistence'ObjectManager;
use Symfony'Bridge'Doctrine'Form'Type'EntityType;
use Symfony'Component'Form'AbstractType;
use Symfony'Component'Form'FormBuilderInterface;
use Symfony'Component'OptionsResolver'OptionsResolver;
class OrganisationType extends AbstractType
{
private $manager;
public function __construct(ObjectManager $objectManager)
{
$this->manager = $objectManager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('subscription', EntityType::class, array(
'class' => 'AppBundle'Entity'Subscription'
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle'Entity'Organisation',
'csrf_protection' => false
));
}
}
在新的Symfony 3.1上,这就像一个魅力(这是处理表单提交的推荐方式,正如之前的评论所述):
public function testAction(Request $request)
{
$organisation = $this->getDoctrine()->getRepository('AppBundle'Entity'Organisation')
->find(1);
$form = $this->createForm(OrganisationType::class, $organisation);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDoctrine()->getManager()->persist($organisation);
$this->getDoctrine()->getManager()->flush();
die('saved into database.');
}
return $this->render('test.html.twig', array(
'testform' => $form->createView()
));
}