使用两个实体创建一个表单表单、创建一个、实体、两个

2023-09-06 23:59:26 作者:你是我今生最美的风景

我问了一个与此类似的问题,但我认为它引起了混乱,所以我决定在这篇文章中用刷过的版本提问.

I asked a similar question to this but I think it caused confusion so I decided to ask in this post with brushed up version.

我想要的是在一个网络表单中打印来自两个不同实体的所有字段,BOTH TYPE.而已.

What I want is to print all fields from two different entities in a single web form, BOTH TYPE. That's it.

注意:我尝试在表单类型(BOTH TYPE)中使用 entitycollection 关键字,但 twig 没有回显任何内容.继续获得;对象的方法品牌"或汽车"无论如何都不存在于树枝行中......

Note: I tried using entity and collection keywords in the form type (BOTH TYPE) but twig doesn't echo anything. Keep getting; Method "brand" OR "car" for object does not exist in twig line whatever....

关系:1 个 Brand 有 N 个 Cars.一对多

Relationship: 1 Brand has N Cars. one-to-many

我阅读了如何嵌入表单集合"、实体字段类型"和集合字段类型",但无论我做什么,都没有用.

I read the 'How to Embed a Collection of Forms', 'entity Field Type' and 'collection Field Type' but whatever I did, didn't work.

品牌实体

namespace CarBrandBundleEntity;

use DoctrineORMMapping as ORM;
use DoctrineCommonCollectionsArrayCollection;

class BrandEntity
{
    protected $id;
    protected $name;
    protected $origin;

    /**
     * @ORMOneToMany(targetEntity = "CarEntity", mappedBy = "brand")
     * @var object $car
     */
    protected $car;

    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->car = new ArrayCollection();
    }
}

汽车实体

namespace CarBrandBundleEntity;

use DoctrineORMMapping as ORM;

class CarEntity
{
    protected $id;
    protected $model;
    protected $price;

    /**
     * @ORMManyToOne(targetEntity="BrandEntity", inversedBy="car")
     * @ORMJoinColumn(name="brand_id", referencedColumnName="id")
     * @var object $brand
     */
    protected $brand;
}

品牌类型

namespace CarBrandBundleFormType;

use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolverInterface;

class BrandType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->setAction($options['action'])
            ->setMethod('POST')
            ->add('name', 'text', array('label' => 'Name'))
            ->add('origin', 'text', array('label' => 'Origin'))
            ->add('button', 'submit', array('label' => 'Add'))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'CarBrandBundleEntityBrandEntity')
        );
    }

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

车型

namespace CarBrandBundleFormType;

use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolverInterface;

class CarType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->setAction($options['action'])
            ->setMethod('POST')
            ->add('model', 'text', array('label' => 'Model'))
            ->add('price', 'text', array('label' => 'Price'))
            ->add('button', 'submit', array('label' => 'Add'))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'CarBrandBundleEntityCarEntity')
        );
    }

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

-------------------------------------------------------------------

--------这部分是我试图让它工作的部分------

-------------------------------------------------------------------

两种类型

namespace CarBrandBundleFormType;

use SymfonyComponentFormAbstractType;
use SymfonyComponentFormTestFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolverInterface;

class BothType extends AbstractType
{
    public function builder(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->setAction($options['action'])
            ->setMethod('POST')
            ->add('brand', 'collection', array('type' => new BrandType()))
            ->add('car', 'collection', array('type' => new CarType()))
            ->add('button', 'submit', array('label' => 'Add'))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'CarBrandBundleEntityBrandEntity',
            'cascade_validation' => true
        ));
    }

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

控制器

namespace CarBrandBundleController;

use CarBrandBundleFormTypeBothType;
use SymfonyBundleFrameworkBundleControllerController;

class BothController extends Controller
{
    public function indexAction()
    {
        $form = $this->createForm(new BothType(), null,
            array('action' => $this->generateUrl('bothCreate')));;

        return $this->render('CarBrandBundle:Default:both.html.twig',
                array('page' => 'Both', 'form' => $form->createView()));
    }
}

树枝

{% block body %}
    {{ form_label(form.brand.name) }}
    {{ form_widget(form.brand.name) }}
    {{ form_label(form.brand.origin) }}
    {{ form_widget(form.brand.origin) }}

    {{ form_label(form.car.model) }}
    {{ form_widget(form.car.model) }}
    {{ form_label(form.car.price) }}
    {{ form_widget(form.car.price) }}
{% endblock %}

推荐答案

使用数组来合成控制器中的两个对象.

Use an array to composite the two objects in your controller.

$formData = array(
    'brand' = new Brand(),
    'car' => new Car(),
);
$builder = $this->createFormBuilder($formData);
$builder->add('brand',new BrandFormType());
$builder->add('car', new CarFormType());

$form = $builder->getForm();

==============================================================
If you really want to make a BothType then just get rid of that collection type.

class BothType extends AbstractType
{
    public function builder(FormBuilderInterface $builder, array $options)
    {
    $builder
        ->setAction($options['action'])
        ->setMethod('POST')
        ->add('brand', new BrandType())
        ->add('car', new CarType())
        ->add('button', 'submit', array('label' => 'Add'))
    ;
    }

    // Controller
    $form = $this->createForm(new BothType(), $formData

当您有多个相同实体类型的实例时使用集合.

collection is used when you have multiple instances of the same entity type.

顺便说一句,为每个复合表单创建类会很快导致表单类型爆炸式增长.因此,除非您打算在多个控制器之间重用 BothFormType,否则我建议您直接在控制器内部构建它.

By the way, creating classes for each composite form can quickly cause an explosion of form types. So unless you plan on reusing your BothFormType among multiple controllers then I'd suggest just building it right inside of the controller.