2016-08-31 99 views
0

我遇到了問題,我認爲這可能是相當基本的,但原因是逃避我。Symfony窗​​體與學說實體 - 關係不加載編輯

我有兩個實體,一個組織和一個訂閱。一個組織與一個訂閱鏈接。

我希望能夠通過表單進行編輯(通過表單創建)。當我做到以下幾點:

$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 
    )); 
} 
} 
+1

首先,你爲什麼要在該實體字段上使用DataTransformer?只要您提供要使用的類,Symfony就可以將整數(由表單的選擇字段提供)轉換爲對象,您可以在字段選項中執行此操作。其次,你能提供例外嗎? – VaN

+0

@VNN你好,我有變壓器只是爲了檢查確保它正在轉換。這是沒有必要的,因爲我已經刪除它。我編輯了我的帖子以顯示實際的異常。感謝您的幫助,這個讓我瘋狂! –

+0

我不熟悉的唯一事情就是處理表單提交的方式。我從來沒有使用'$ form-> submit($ paramFetcher-> all())'。根據文檔,處理表單的方式是提交如下:'$ form-> handleRequest($ request);如果($ form-> isSubmitted()&& $ form-> isValid()){ $ organization = $ form-> getData(); // ...執行某些操作,例如將任務保存到數據庫中# 請參閱http://symfony.com/doc/current/forms.html#handling-form-submissions – VaN

回答

0

在一個新鮮的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() 
    )); 

} 
+0

非常感謝您的努力。我沒有找到這個來源,儘管我懷疑它可能與序列化組或某事有關。我不得不暫時繼續前進,但是當我重新開始時,我會用答案更新問題。 –