symfony多个实体在一个形式的问题,我不明白


symfony multiple Entities in one Form issue that I do not understand

开始使用symfony2。到目前为止我很喜欢。我尝试了一个多实体的形式来弄清楚,如果形式构建器是可用于我的需要。首先是我的实体:

客户实体

    namespace CustomerBundle'Entity;
    use Doctrine'Common'Collections'ArrayCollection;
        use Symfony'Component'DependencyInjection'ContainerInterface;
        use Doctrine'ORM'Mapping as ORM;
        use UserBundle'Entity'Users;
        /**
         * @ORM'Table(name="customers")
         * @ORM'HasLifecycleCallbacks
         * @ORM'Entity(repositoryClass="CustomerBundle'Entity'CustomerRepository")
         */
        class Customer
        {
            /**
             * @var ContainerInterface
             */
            protected $container;
            /**
             * @ORM'Id
             * @ORM'Column(name="id", type="integer", nullable=false)
             * @ORM'GeneratedValue(strategy="IDENTITY")
             */
            protected $Id;
            /**
             * @ORM'Column(name="nickname", type="string", length=50, unique=true)
             */
            protected $NickName;
            /**
             * @ORM'OneToMany(targetEntity="'CustomerBundle'Entity'Address", mappedBy="Customer")
             **/
            protected $Addresses;
            /**
             * @ORM'OneToMany(targetEntity="'CustomerBundle'Entity'Mail", mappedBy="Customer")
             **/
            protected $Emails;
            /**
             * @ORM'ManyToMany(targetEntity="'UserBundle'Entity'Users")
             * @ORM'JoinTable(name="customers_mapping_users",
             *      joinColumns={@ORM'JoinColumn(name="user_id", referencedColumnName="id")},
             *      inverseJoinColumns={@ORM'JoinColumn(name="customer_id", referencedColumnName="id")}
             *      )
             **/
            protected $Users;
            /**
             * @ORM'Column(name="lead_type", type="string", length=50, nullable=true)
             */
            protected $LeadType;
            /**
             * @ORM'ManyToOne(targetEntity="'UserBundle'Entity'Users", fetch="EXTRA_LAZY")
             * @ORM'JoinColumn(name="lead__owner_user_id", referencedColumnName="id")
             */
            protected $LeadOwner;
            /**
             * @ORM'OneToMany(targetEntity="'CustomerBundle'Entity'Note", mappedBy="Customer")
             **/
            protected $Notes;
            protected $Reminders;
            protected $SupportTickets;
            protected $Invoices;
            protected $Documents;
            /**
             * @ORM'OneToMany(targetEntity="'CustomerBundle'Entity'Todo", mappedBy="Customer")
             **/
            protected $Todos;
            /**
             * @return Todo[]
             */
            public function getTodos()
            {
                return $this->Todos;
            }
            /**
             * @param Todo $todo
             */
            public function addTodo(Todo $todo)
            {
                $this->Todos->add($todo);
            }
            /**
             * @param Todo $todo
             *
             * @return bool
             */
            public function hasTodo(Todo $todo=null)
            {
                return $this->Todos->contains($todo);
            }
            /**
             * @param Todo $todo
             *
             * @return $this
             */
            public function removeTodo(Todo $todo)
            {
                $this->Todos->removeElement($todo);
                return $this;
            }
}

我的地址实体

<?php
    namespace CustomerBundle'Entity;
        use Symfony'Component'DependencyInjection'ContainerInterface;
        use Doctrine'ORM'Mapping as ORM;
        /**
         * @ORM'Table(name="customers_address")
         * @ORM'HasLifecycleCallbacks
         * @ORM'Entity(repositoryClass="CustomerBundle'Entity'AddressRepository")
         */
        class Address
        {
            /**
             * @var ContainerInterface
             */
            protected $container;
            /**
             * @ORM'Id
             * @ORM'Column(name="id", type="integer", nullable=false)
             * @ORM'GeneratedValue(strategy="IDENTITY")
             */
            protected $Id;
            /**
             * @ORM'ManyToOne(targetEntity="CustomerBundle'Entity'Customer", inversedBy="Addresses")
             * @ORM'JoinColumn(name="customer_id", referencedColumnName="id")
             **/
            protected $Customer;
            /**
             * @ORM'Column(name="first_name", type="string", length=50, nullable=true)
             */
            protected $FirstName;
            /**
             * @ORM'Column(name="last_name", type="string", length=50, nullable=true)
             */
            protected $LastName;
            /**
             * @ORM'Column(name="company_name", type="string", length=50, nullable=true)
             */
            protected $CompanyName;
            /**
             * @ORM'Column(name="street1", type="string", length=250, nullable=true)
             */
            protected $Street1;
            /**
             * @ORM'Column(name="street2", type="string", length=250, nullable=true)
             */
            protected $Street2;
            /**
             * @ORM'Column(name="street3", type="string", length=250, nullable=true)
             */
            protected $Street3;
            /**
             * @ORM'Column(name="zipcode", type="string", length=10, nullable=true)
             */
            protected $Zipcode;
            /**
             * @ORM'Column(name="city", type="string", length=50, nullable=true)
             */
            protected $City;
            /**
             * @ORM'Column(name="country", type="string", length=50, nullable=true)
             */
            protected $Country;
            /**
             * @ORM'Column(name="phone", type="string", length=50, nullable=true)
             */
            protected $Phone;
            /**
             * @ORM'Column(name="fax", type="string", length=50, nullable=true)
             */
            protected $Fax;
            /**
             * @ORM'Column(name="tax_id", type="string", length=50, nullable=true)
             */
            protected $TaxId;
}

最后但同样重要的是

    namespace CustomerBundle'Entity;
    use HomeBundle'Traits'CreateTrait;
        use HomeBundle'Traits'serializeTrait;
        use HomeBundle'Traits'UpdateTrait;
        use Symfony'Component'DependencyInjection'ContainerInterface;
        use Doctrine'ORM'Mapping as ORM;
        /**
         * @ORM'Table(name="customer_mail")
         * @ORM'HasLifecycleCallbacks
         * @ORM'Entity(repositoryClass="CustomerBundle'Entity'MailRepository")
         */
        class Mail
        {
            /**
             * @var ContainerInterface
             */
            protected $container;
            /**
             * @ORM'Id
             * @ORM'Column(name="id", type="integer", nullable=false)
             * @ORM'GeneratedValue(strategy="IDENTITY")
             */
            protected $Id;
            /**
             * @ORM'Column(name="email", type="string", length=255, unique=true)
             */
            protected $Email;
            /**
             * @ORM'ManyToOne(targetEntity="CustomerBundle'Entity'Customer", inversedBy="Emails")
             * @ORM'JoinColumn(name="customer_id", referencedColumnName="id")
             **/
            protected $Customer;
}

根据http://symfony.com/doc/current/cookbook/form/form_collections.html我添加了三种表单类型:

地址:

        use Symfony'Component'Form'AbstractType;
        use Symfony'Component'Form'FormBuilderInterface;
        use Symfony'Component'OptionsResolver'OptionsResolver;
        class AddressType extends AbstractType
        {
            public function buildForm(FormBuilderInterface $builder, array $options)
            {
                $builder
                    ->add('FirstName','text',array('label'=>'firstname'))
                    ->add('LastName','text',array('label'=>'lastname'))
                    ->add('CompanyName','text',array('label'=>'company name'))
                    ->add('Street1','text',array('label'=>'street 1'))
                    ->add('Street2','text',array('label'=>'street 2'))
                    ->add('Street3','text',array('label'=>'street 3'))
                    ->add('Zipcode','text',array('label'=>'zip code'))
                    ->add('City','text',array('label'=>'city'))
                    ->add('Country','text',array('label'=>'country'))
                    ->add('Phone','text',array('label'=>'phone'))
                    ->add('Fax','text',array('label'=>'fax'))
                    ->add('TaxId','text',array('label'=>'taxid'));
            }
            public function configureOptions(OptionsResolver $resolver)
            {
                $resolver->setDefaults(
                    array(
                    'data_class' => 'CustomerBundle'Entity'Address',
                    )
                );
            }
            public function getName()
            {
                return 'address';
            }
        }
邮件:

        use Symfony'Component'Form'AbstractType;
        use Symfony'Component'Form'FormBuilderInterface;
        use Symfony'Component'OptionsResolver'OptionsResolver;
        class MailType extends AbstractType
        {
            public function buildForm(FormBuilderInterface $builder, array $options)
            {
                $builder
                    ->add('Email','email',array('label'=>'email'));
            }
            public function configureOptions(OptionsResolver $resolver)
            {
                $resolver->setDefaults(
                    array(
                    'data_class' => 'CustomerBundle'Entity'Mail',
                    )
                );
            }
            public function getName()
            {
                return 'mail';
            }
        }

和客户作为顶级实例:

    <?php
        namespace CustomerBundle'Form'Type;
        use Symfony'Component'Form'AbstractType;
        use Symfony'Component'Form'FormBuilderInterface;
        use Symfony'Component'OptionsResolver'OptionsResolver;
        class CustomerType extends AbstractType
        {
            public function buildForm(FormBuilderInterface $builder, array $options)
            {
                $builder
                    ->add('NickName','text',array('label'=>'customers nickname'))
                    ->add('address','collection',array('type'=>new AddressType()))
                    ->add('mail','collection',array('type'=>new MailType()));
            }
            public function configureOptions(OptionsResolver $resolver)
            {
                $resolver->setDefaults(
                    array(
                        'data_class' => 'CustomerBundle'Entity'Customer',
                    )
                );
            }
            public function getName()
            {
                return 'customer';
            }
        }

在My Controller的create action中,我添加了这个:

/**
 * @Route("/Customers/Create", name="crm_customers_create")
 * @Template()
 */
public function createAction()
{
    $customer = new Customer();
    $address = new Address();
    $mail = new Mail();
    $customer->addAddress($address);
    $customer->addEmail($mail);
    $form = $this->createForm(new CustomerType(),$customer);
    return array(
        'form'=>$form->createView(),
    );
}

和我的小树枝模板包含:

{% extends "HomeBundle:Core:base.html。树枝"%}

    {% block title %}CustomerBundle:Customers:create{% endblock %}
    {% block body %}
        <div class="col-xs-10 col-xs-offset-1">
            <fieldset>
                <legend>{% trans %}create a new Customer{% endtrans %}</legend>
                {{ form_start(form) }}
                {{ form_widget(form) }}
                {{ form_end(form) }}
            </fieldset>
        </div>
    {% endblock %}

所以当我打开页面时,我只得到这个输出:

预期参数类型为"array or ('Traversable and 'ArrayAccess)", "boolean"给定500内部服务器错误-意外类型异常堆栈跟踪

        in vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php at line 84  -
                    }
                    if (!is_array($data) && !($data instanceof 'Traversable && $data instanceof 'ArrayAccess)) {
                        throw new UnexpectedTypeException($data, 'array or ('Traversable and 'ArrayAccess)');
                    }
                    // First remove all rows
        at ResizeFormListener ->preSetData (object(FormEvent), 'form.pre_set_data', object(EventDispatcher))
        at call_user_func (array(object(ResizeFormListener), 'preSetData'), object(FormEvent), 'form.pre_set_data', object(EventDispatcher))
        in app/cache/dev/classes.php at line 1826  +
        at EventDispatcher ->doDispatch (array(array(object(ResizeFormListener), 'preSetData')), 'form.pre_set_data', object(FormEvent))
        in app/cache/dev/classes.php at line 1759  +
        at EventDispatcher ->dispatch ('form.pre_set_data', object(FormEvent))
        in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php at line 43  +
        at ImmutableEventDispatcher ->dispatch ('form.pre_set_data', object(FormEvent))
        in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 342  +
        at Form ->setData (false)
        in vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php at line 57  +
        at PropertyPathMapper ->mapDataToForms (object(Customer), object(RecursiveIteratorIterator))
        in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 396  +
        at Form ->setData (object(Customer))
        in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 488  +
        at Form ->initialize ()
        in vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php at line 226  +
        at FormBuilder ->getForm ()
        in vendor/symfony/symfony/src/Symfony/Component/Form/FormFactory.php at line 39  +
        at FormFactory ->create (object(CustomerType), object(Customer), array())
        in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php at line 250  +
        at Controller ->createForm (object(CustomerType), object(Customer))
        in src/CustomerBundle/Controller/CustomersController.php at line 47  +
        at CustomersController ->createAction ()
        at call_user_func_array (array(object(CustomersController), 'createAction'), array())
        in app/bootstrap.php.cache at line 3109  +
        at HttpKernel ->handleRaw (object(Request), '1')
        in app/bootstrap.php.cache at line 3071  +
        at HttpKernel ->handle (object(Request), '1', true)
        in app/bootstrap.php.cache at line 3222  +
        at ContainerAwareHttpKernel ->handle (object(Request), '1', true)
        in app/bootstrap.php.cache at line 2444  +
        at Kernel ->handle (object(Request))
        in web/app_dev.php at line 29  +

我不知道问题是从哪里来的,因为我看不出是哪个实体导致了故障。到目前为止一切看起来都很好。我还试图只访问其中一个表单字段,但这导致了同样的异常。如果您能帮助我解决这个问题,我将不胜感激。

表单字段名必须匹配实体属性名。CustomerType表单字段addressemailCustomer实体属性AddressesEmails不匹配