2012-09-22 23 views
9

Symfony 2.1.3-देव और सिद्धांत 2.3का उपयोग करते हुए इकाई फ़ील्ड प्रकार

मैं एक रूप है जो डेटा की एक लौटे सेट को फ़िल्टर करने के लिए एक उपयोगकर्ता के लिए कई विकल्प प्रदान करते हैं बनाने का प्रयास कर रहा हूँ (Entity\EngineCodes) का उपयोग करना । यह फॉर्म 1 टेक्स्ट इनपुट फ़ील्ड (id) और 3 चुनिंदा फ़ील्ड (module, type, status) से बना है। मैं EngineCodes इकाई से 3 चुनिंदा फ़ील्ड के मान उत्पन्न करने के लिए Symfony2 entity form_type का उपयोग करने का प्रयास कर रहा हूं।

चूंकि मैं किसी भी 3 चयनित फ़ील्ड के संयोजन का उपयोग करके तालिका को फ़िल्टर करना चाहता हूं। 2.1 दस्तावेज़ों के आधार पर, मैंने फॉर्मटाइप (EngineCodesFilterType) बनाने का निर्णय लिया और प्रत्येक फ़ील्ड के लिए अद्वितीय मानों का एक सेट वापस करने के लिए कथन के साथ entity प्रकार के फॉर्म फ़ील्ड को सेट करें।

दुर्भाग्यवश, मुझे अनुवर्ती त्रुटि प्राप्त हो रही है, और मुझे बिल्कुल यकीन नहीं है कि यह किसी ऑब्जेक्ट के बजाय सरणी क्यों लौट रहा है।

The form's view data is expected to be an instance of class 
    Vendor\IndexBundle\Entity\EngineCodes, but is a(n) array. 
    You can avoid this error by setting the "data_class" option 
    to null or by adding a view transformer that transforms a(n) 
    array to an instance of Vendor\IndexBundle\Entity\EngineCodes. 

अगर मैं null को data_class निर्धारित करते हैं, मैं यह त्रुटि प्राप्त:

A "__toString()" method was not found on the objects of type 
    "Vendor\IndexBundle\Entity\EngineCodes" passed to the choice 
    field. To read a custom getter instead, set the option 
    "property" to the desired property path. 

मैं अभी भी इन Symfony2 सुविधाओं सीख रहा हूँ के बाद से, मेरा लक्ष्य निर्माण और प्रारूप के संबंध में 2.1 डॉक्स मिलान करने के लिए था जितना संभव।

public function displayAction() { 

    // ... 

    $entity = $this->getDoctrine()->getEntityManager() 
     ->getRepository('VendorIndexBundle:EngineCodes') 
     ->findAll(); 

    // ... 

    $form = $this->createForm(new EngineCodesFilterType(), $entity); 

    // ... 

    return $this->render(
     'VendorIndexBundle::layout.html.twig', 
     array(
      'entity' => $entity, 
      'form' => $form->createView(),)); 

यहाँ प्रपत्र प्रकार है: यहाँ

class EngineCodesFilterType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add(
      'id', 
      'integer', 
      array(
       'label' => 'Code ID',)); 
     $builder->add(
      'status', 
      'entity', 
      array(
       'label' => 'Code Status', 
       'class' => 'VendorIndexBundle:EngineCodes', 
       'query_builder' => function(EntityRepository $er) 
        { 
         return $er->createQueryBuilder('u') 
          ->select('u.status') 
          ->add('groupBy', 'u.status'); 
        }, 
       'multiple' => true,)); 
     $builder->add(
      'type', 
      'entity', 
      array(
       'label' => 'Code Type', 
       'class' => 'VendorIndexBundle:EngineCodes', 
       'query_builder' => function(EntityRepository $er) 
        { 
         return $er->createQueryBuilder('u') 
          ->select('u.type') 
          ->add('groupBy' ,'u.type'); 
        }, 
       'multiple' => true,)); 
     $builder->add(
      'module', 
      'entity', 
      array(
       'label' => 'Code Module', 
       'class' => 'VendorIndexBundle:EngineCodes', 
       'query_builder' => function(EntityRepository $er) 
        { 
         return $er->createQueryBuilder('u') 
          ->select('u.module') 
          ->add('groupBy', 'u.module'); 
        }, 
       'multiple' => true,)); 
    } 

    public function getName() 
    { 
     return 'EngineCodesFilter'; 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(
      array(
       'data_class'  => 'Vendor\IndexBundle\Entity\EngineCodes', 
       /*'data_class'  => null,*/ 
       'validation_groups' => 'filter',)); 
    } 
} 

और Vendor\Entity\EngineCodes वर्ग है:

/** 
* Vendor\IndexBundle\Entity\EngineCodes 
* 
* @ORM\Table(name="engine_codes") 
* @ORM\Entity(repositoryClass="Vendor\IndexBundle\Entity\EngineCodesRepository") 
* @UniqueEntity(fields="id", message="ID already in use! Enter a unique ID for the code.") 
*/ 
class EngineCodes 
{ 
    /** 
    * @var integer $id 
    * 
    * @ORM\Column(name="id", type="integer", nullable=false, unique=true) 
    * @ORM\Id 
    * @Assert\NotBlank(message="ID cannot be blank!") 
    * @Assert\Regex(pattern="/^\d+$/", match=true, message="ID must be an integer!") 
    * @Assert\MinLength(limit=8, message="ID must be 8 numbers in length!") 
    * @Assert\MaxLength(limit=8, message="ID must be 8 numbers in length!") 
    */ 
    private $id; 

    /** 
    * @var string $token 
    * 
    * @ORM\Column(name="token", type="string", length=255, nullable=false, unique=true) 
    */ 
    private $token; 

    /** 
    * @var boolean $status 
    * 
    * @ORM\Column(name="status", type="integer", nullable=false) 
    * @Assert\NotBlank(message="Status cannot be blank!") 
    */ 
    private $status; 

    /** 
    * @var string $module 
    * 
    * @ORM\Column(name="module", type="string", length=255, nullable=false) 
    * @Assert\NotBlank(message="Module cannot be blank!") 
    */ 
    private $module; 

    /** 
    * @var string $submodule 
    * 
    * @ORM\Column(name="submodule", type="string", length=255, nullable=false) 
    * @Assert\NotBlank(message="Submodule cannot be blank!") 
    */ 
    private $submodule; 

    /** 
    * @var string $type 
    * 
    * @ORM\Column(name="type", type="string", length=255, nullable=false) 
    * @Assert\NotBlank(message="Type cannot be blank!") 
    */ 
    private $type; 

    /** 
    * @var string $description 
    * 
    * @ORM\Column(name="description", type="text", nullable=false) 
    * @Assert\NotBlank(message="Description cannot be blank!") 
    */ 
    private $description; 

    /** 
    * @var string $title 
    * 
    * @ORM\Column(name="title", type="string", length=255, nullable=false) 
    * @Assert\NotBlank(message="Title cannot be blank!") 
    */ 
    private $title; 

    /** 
    * @var string $definition 
    * 
    * @ORM\Column(name="definition", type="text", nullable=true) 
    */ 
    private $definition; 

    /** 
    * @var string $color 
    * 
    * @ORM\Column(name="color", type="string", length=10, nullable=true) 
    */ 
    private $color; 

    /** 
    * @var \DateTime $createTimestamp 
    * 
    * @ORM\Column(name="create_timestamp", type="datetime", nullable=false) 
    */ 
    private $createTimestamp; 

    /** 
    * @var Accounts 
    * 
    * @ORM\ManyToOne(targetEntity="Accounts") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="create_account_fk", referencedColumnName="id") 
    * }) 
    */ 
    private $createAccountFk; 


    // getters and setters ... 

    /** 
    * Set createAccountFk 
    * 
    * @param Vendor\IndexBundle\Entity\Accounts $createAccountFk 
    * @return EngineCodes 
    */ 
    public function setCreateAccountFk(\Vendor\IndexBundle\Entity\Accounts $createAccountFk = null) 
    { 
     $this->createAccountFk = $createAccountFk; 

     return $this; 
    } 

    /** 
    * @ORM\PrePersist 
    */ 
    public function setCreateTimestampValue() 
    { 
     $this->createTimestamp = new \DateTime(); 
    } 
} 

उत्तर

14

आपका पहला समस्या यह है कि $entity एक इकाई नहीं है, बल्कि संस्थाओं की एक सरणी (जो क्या findAll() विधि द्वारा दिया जाता है) है। जब आपने फॉर्म प्रकार को परिभाषित किया था, तो आपने कहा था कि आपको किसी इकाई से फ़ॉर्म बनाने की उम्मीद है (यही data_class विकल्प है) और यही कारण है कि आपको पहली त्रुटि मिलती है।

यदि आप data_class को शून्य में सेट करते हैं तो आप कह रहे हैं कि आप किसी इकाई से फ़ॉर्म बनाने की अपेक्षा नहीं करते हैं, इसलिए यह आपकी इकाइयों की सरणी स्वीकार करेगा और शिकायत नहीं करेगा। लेकिन, आप फॉर्म प्रकार के लिए इकाइयों की एक सरणी क्यों गुजर रहे हैं? यह सिर्फ एक फ़िल्टर फ़ॉर्म है जो आपको अपनी संस्थाओं को फ़िल्टर करने के लिए चार संभावित मान चुनने की अनुमति देता है। इसके अंतर्निहित डेटा के रूप में इकाइयों की एक सरणी की आवश्यकता नहीं है। यदि आपको लगता है कि कोड, प्रकार और स्थिति फ़ील्ड के मान प्राप्त करने के लिए आपको इसकी आवश्यकता है, तो ऐसा नहीं है क्योंकि वे पहले से ही आपके क्वेरी बिल्डर्स के साथ लाए गए हैं। तो अपने नियंत्रक कोड सिर्फ होना चाहिए: क्योंकि आप तीन प्रपत्र फ़ील्ड्स जोड़ रहे हैं और हर एक तुम एक इकाई सूची से चयन कर सकते हैं

public function displayAction() { 

// ... 

$entity = $this->getDoctrine()->getEntityManager() 
    ->getRepository('VendorIndexBundle:EngineCodes') 
    ->findAll(); 

// ... 

$form = $this->createForm(new EngineCodesFilterType()); 

// ... 

return $this->render(// ... 

तो फिर तुम अन्य त्रुटि मिलती है। लेकिन, आप इस इकाई को "कैसे दिखाते हैं"? सिम्फनी नहीं जानता कि यह इकाई आपको इकाई का प्रतिनिधित्व करने के लिए कौन सा फ़ील्ड दिखाएगी, इसलिए यह इस त्रुटि को फेंकता है।

यह त्रुटि इंजन कोड क्लास में __toString() विधि जोड़कर तय की जा सकती है, जो सिर्फ "हे, यह मैं इस वर्ग को कैसे दिखाना चाहता हूं" कहता है, लेकिन हालांकि त्रुटि को फेंक नहीं दिया जाएगा, यह काम नहीं करेगा उम्मीद है क्योंकि तीनों में से प्रत्येक फ़ील्ड एक अलग संपत्ति दिखाना चाहता है।

एक और समाधान फॉर्म फ़ील्ड के property विकल्प का उपयोग करना है, यह कहने के लिए कि अंतर्निहित ऑब्जेक्ट की कौन सी संपत्ति डेटा प्रदर्शित करने के लिए आप उपयोग करना चाहते हैं।

उदाहरण के लिए:

$builder->add(
     'status', 
     'entity', 
     array(
      'label' => 'Code Status', 
      'class' => 'VendorIndexBundle:EngineCodes', 
      'property' => 'status' 
      'query_builder' => function(EntityRepository $er) 
       { 
        return $er->createQueryBuilder('u') 
         ->select('u.status') 
         ->add('groupBy', 'u.status'); 
       }, 
      'multiple' => true,)); 
+1

+1। – gremo

+1

अह्ह्ह, यह पूरी तरह से समझ में आता है कि संस्थाओं की मेरी सरणी को फॉर्म में लागू न करें। उस अवलोकन के लिए धन्यवाद। –

+0

और अब यह प्रतीत होता है कि मेरा query_builder कथन एरे/ऑब्जेक्ट्स को वापस नहीं कर रहा है बल्कि बल्कि पूर्णांक और तारों को वापस नहीं कर रहा है। सुबह में ताजा आंखों के साथ फिर से जाना होगा। –

11

आप बस याद कर रहे हैं

यहाँ नियंत्रक के भीतर कार्य है "स्थिति", "प्रकार" और "मॉड्यूल" इकाई प्रकारों में property option:

property

type: string

This is the property that should be used for displaying the entities as text in the HTML element. If left blank, the entity object will be cast into a string and so must have a __toString() method.

+2

अवलोकन के लिए धन्यवाद। मजेदार कैसे एक घंटे के लिए दूर चलना और फिर वापस आना बहुत स्पष्ट त्रुटि संदेश अधिक समझ में मदद करता है। सरणी त्रुटि खोजने के लिए –

संबंधित मुद्दे