How to Embed a Collection of Forms - one-to-many/many-to-one

606 Views Asked by At

I have 3 entities:

Product -> (1:m) Product2Attribute -> (m:1) Attribute

Each Product can have more attributes. The value of attribute is store in associative entity Product2Attribute.

I would like to generate attribute fields in Product form. I have a product type and embed new collection of productAttributeAssociations and create new form type Product2AttributeType which contains 2 field id and value. The form are rendered:

{% for productAttribute in form.productAttributeAssociations %}
        {{ form_label(form.productAttribute.value) }}
        {{ form_widget(form.productAttribute.value) }}
{% endfor %}

Product form:

public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder
        ->add('name', 'text')
        ->add('title', 'text')
        ->add('number', 'text')
        ->add('netPrice', 'text')
        ->add('grossPrice', 'text')
        ->add('description', 'textarea')
        ->add('category', 'entity', array(
            'class' => 'XXXBundle:Category',
            'query_builder' => function (EntityRepository $er) {
                return $er->createQueryBuilder('c')
                    ->orderBy('c.root', 'ASC')
                    ->addOrderBy('c.lft', 'ASC');
            },
            'property' => 'indentedTitle',
            'multiple' => true
        ))
        ->add('productAttributeAssociations', 'collection', array(
            'type' => new \XXXBundle\Form\Product2AttributeType()
        ))
        ->add('save', 'submit');
}

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

public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
        'data_class' => 'XXXBundle\Entity\Product',
        'csrf_protection' => true,
        'csrf_field_name' => '_token',
        'intention' => 'product_item',
    ));
}

and Product2AttributeType:

public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder->add('id', 'hidden');
    $builder->add('value', 'text');
}

public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
        'data_class' => 'XXXBundle\Entity\Product2Attribute',
    ));
}

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

When I populate form by Product without any attributes, the form is rendered without any attribute fields, but when i use Product with at least one attribute the error occurs:

 The forms view data is expected to be of type scalar, array or an instance     
    of \ArrayAccess, but is an instance of class 
    XXXBundle\Entity\Product2Attribute.   You can avoid this error by setting 
    the "data_class" option to "XXXBundle\Entity\Product2Attribute" or by adding 
    a view transformer that transforms an instance of class 
    XXXBundle\Entity\Product2Attribute to scalar, array or an instance of 
    \ArrayAccess.
    500 Internal Server Error - LogicException

And my questions are:

Thank you.

0

There are 0 best solutions below