2013-08-10 5 views
15

के साथ खाली ऑब्जेक्ट्स बनाने से रोकें 0 सबसे पहले, मुझे यकीन नहीं है कि यह सोनाटा मुद्दा या सिम्फनी 2 है, यह पहली बार है कि मैं एसएफ 2 फॉर्मों के साथ काम कर रहा हूं रिश्ते।SonataAdmin/Symfony2 को sonata_type_admin एम्बेडेड व्यवस्थापक

यहाँ समस्या है:

मैं दो वर्गों है, उन्हें पुराने पसंदीदा कॉल: Car और Wheel। कार के पास व्हील के साथ वैकल्पिक एक-से-एक संबंध है (यह उदाहरण के लिए है, बस इसके साथ जाएं ...)। मैंने CarAdmin कक्षा के साथ सोनाटाएडमिन स्थापित किया है जो sonata_type_admin का उपयोग करके 0 व्हील के लिए किसी भी डेटा दर्ज किए बिना कार बनाने का प्रयास करता है।

हालांकि, सबमिट पर (कहीं भी $ form-> bind()/$ form-> सबमिट() जहां तक ​​मैं ट्रेस कर सकता हूं) सिम्फनी और/या सोनाटा एक व्हील को तुरंत चालू कर रहा है और इसे जारी रखने की कोशिश कर रहा है (सभी के साथ इसके मूल्य null) के रूप में। चूंकि व्हील में कुछ गैर-शून्य बाधाएं हैं, इससे डीबीएक्सएक्सप्शन शिकायत करता है कि आप नल vlaues के साथ एक व्हील इंसर्ट नहीं कर सकते हैं।

यह शरारती है और मैं इसे रोकना बंद करना चाहता हूं। यदि मैं व्हील के लिए कोई विवरण नहीं डालता हूं, तो मैं अपने कोड और डेटाबेस को खतरे में रखते हुए एक प्रेत व्हील नहीं चाहता हूं। मुझे उम्मीद है कि यदि मैं कोई डेटा दर्ज नहीं करता हूं तो इसमें डालने/जारी रखने के लिए कुछ भी नहीं है, इसलिए यह अकेला रह गया है। लेकिन यह नहीं हो रहा है ... कोई विचार यह समझ में आता है कि इसे समझ में कैसे लाया जाए?


यहां लंबा संस्करण है, कोड ब्लॉक और सब कुछ के साथ:

ORM परिभाषाओं पहले:

# MyNS\MyBundle\Resources\Config\Doctrine\Car.orm.yml 
MyNS\MyBundle\Entity\Car: 
    type: entity 
    repositoryClass: MyNS\MyBundle\Entity\Repositories\CarRepository 
    table: test_cars 
    id: 
    id: 
     type:      integer 
     generator:    { strategy: AUTO } 
    fields: 
    color: 
     type:      string 
     length:     50 
    owner: 
     type:      string 
     length:     50 
     nullable:     true 
    oneToOne: 
    leftFrontWheel: 
     targetEntity:    Wheel 
     cascade:     [ persist ] 
     joinColumn: 
     name:     leftFrontWheelId 
     referencedColumnName: id 


# MyNS\MyBundle\Resources\Config\Doctrine\Wheel.orm.yml 
MyNS\MyBundle\Entity\Wheel: 
    type: entity 
    repositoryClass: MyNS\MyBundle\Entity\Repositories\WheelRepository 
    table: test_wheels 
    id: 
    id: 
     type:      integer 
     generator:    { strategy: AUTO } 
    fields: 
    diameter: 
     type:      integer 
     length:     5 

फिर SonataAdmin कक्षाएं:

namespace MyNS\MyBundle\Admin 

use ... 

class CarAdmin extends Admin 
{ 
    protected function configureFormFields(FormMapper $formMapper) 
    { 
     $formMapper 
      ->add('color',    null, array('required' => true)) 
      ->add('owner',    null, array('required' => false)) 
      ->add('leftFrontWheel',  'sonata_type_admin', array('delete' => false)) 
     ; 
    } 

    protected function configureListFields(ListMapper $listMapper) { ... } 
} 

और

namespace MyNS\MyBundle\Admin; 

use ... 

class WheelAdmin extends Admin 
{ 
    protected function configureFormFields(FormMapper $formMapper) 
    { 
     $formMapper 
      ->add('diameter', null, array('required' => false)) 
     ; 
    } 

    protected function configureListFields(ListMapper $listMapper) { ... } 
} 

और अंत में admin.yml प्रविष्टियों:

services: 
    sonata.admin.car: 
     class: MyNS\MyBundle\Admin\CarAdmin 
     tags: 
      - { name: sonata.admin, manager_type: orm, label: "Car" } 
     arguments: 
      - ~ 
      - MyNS\MyBundle\Entity\Car 
      - 'SonataAdminBundle:CRUD' 
     calls: 
      - [ setTranslationDomain, [MyNS\MyBundle]] 
    sonata.admin.wheel: 
     class: MyNS\MyBundle\Admin\WheelAdmin 
     tags: 
      - { name: sonata.admin, manager_type: orm, label: "Wheel" } 
     arguments: 
      - ~ 
      - MyNS\MyBundle\Entity\Wheel 
      - 'SonataAdminBundle:CRUD' 
     calls: 
      - [ setTranslationDomain, [MyNS\MyBundle]] 

अपेक्षित/आवश्यक व्यवहार:

  • प्रदर्शन तीन क्षेत्रों के साथ एक रूप है:

    • car.color (आवश्यक)
    • car.owner (वैकल्पिक)
    • car.wheel.diameter (वैकल्पिक)
  • अगर car.wheel.diameter खाली छोड़ा जाता है तो कोई व्हील बनाया जाना चाहिए और test_cars.leftFrontWheelId डेटाबेस में null रहना चाहिए

  • अगर car.wheel।व्यास दर्ज किया गया है तो एक पहिया बनाया है और कार से जोड़ा जाना चाहिए

प्रश्न (यह मौजूदा config के साथ ठीक से काम करने लगता है): मैं कैसे इस प्रणाली के रूप में ऊपर व्यवहार करने के लिए मिलता है?

+4

मुझे लगता है कि मैंने इसके लिए एक कार्यवाही तैयार करने में कामयाब रहा है, लेकिन एक बेहतर तरीका होना चाहिए! (कारएडमिन में मैंने प्रीपेर्सिस्ट() और प्रीअपडेट() विधियों को जोड़ा है जो जांचते हैं कि व्हील में व्यास की कमी है या नहीं। अगर यह है (यानी यह अमान्य है) तो '' कार-> सेट लेफ्टफ्रंटहेल (शून्य) '' रिश्ते को साफ़ करता है और इसे एक खाली व्हील जारी रखने की कोशिश कर रहा है।) – caponica

+0

सोनाटा यादृच्छिक रूप से दिखाई देने वाली बगों से प्रवण है, लेकिन उचित रूप से अक्सर। एक नया संस्करण देखने का प्रयास करें, क्योंकि आपके द्वारा वर्णित व्यवहार मेरे (पुराने) संस्करण में नहीं होता है। सौभाग्य! – likeitlikeit

+0

ठीक है, मैं सोनाटाएडमिन का नवीनतम (देव-मास्टर) संस्करण का उपयोग कर रहा हूं, इसलिए मुझे नहीं लगता कि वहां एक नया है :) सिम्फनी के साथ पर्याप्त अनुभव नहीं हुआ है, यह जानने के लिए कि यह एक सिम्फनी मुद्दा है या सोनाटा एक है, जब मैं निश्चित रूप से पता है कि मैं उचित मुद्दा उठाऊंगा। – caponica

उत्तर

0

यह 'required' => false अनुपलब्ध होने के कारण हो सकता है, नहीं?

protected function configureFormFields(FormMapper $formMapper) { 
    $formMapper 
     ->add('color',    null, array('required' => true)) 
     ->add('owner',    null, array('required' => false)) 
     ->add('leftFrontWheel',  'sonata_type_admin', array('required' => false, 'delete' => false)) 
    ; 
} 
0

की तरह कुछ के लिए अपने Wheel प्रपत्र फ़ील्ड को बदलें:

$formMapper 
    // ... 
    ->add('leftFrontWheel', 'sonata_type_admin', array(
     'delete' => false, 
     'by_reference => true, 
     'required' => false, 
    )) 
    // ... 

by_referencedocumentation

देखें यदि यह पर्याप्त नहीं है, अपने माता पिता के व्यवस्थापक कक्षा में एक prePersist हुक का उपयोग करें और जो क्षेत्र आप की दुकान का प्रबंधन । यानी:

// Fire on submit, before the object persisting 
public function prePersist($object) 
    if ($wheel = $object->getLeftFrontWheel()) { 
     if (!$wheel->getYourNonNullableField()) { 
      $object->setLefTFrontWheel(null); 
     } 
    } 
} 
संबंधित मुद्दे