1
votes

i am trying to add fields to my registration form with FosUserBundle.

Adding normal fields to the Userclass like "name", "age" e.g is easy to do:

class RegistrationFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    // add your custom field
    $builder
        ->add('name')
    ;
}

public function getParent()
{
    return 'fos_user_registration';
}

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

This is all working and the new fields are written to my database table.

But how do i add there a new FormType into the Registration type of the Fos Bundle, like: A user can have an Address, which is related OneToMany.

I tried it with the following, by first creating the address class and giving him one user:

   /**
 * @ORM\ManyToOne(targetEntity="User", inversedBy="addresses")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 */
protected $user;

And then by adding addresses to the User class:

 /**
 * @ORM\OneToMany(targetEntity="Address", mappedBy="user")
 */
protected $addresses;

public function __construct()
{
    parent::__construct();

    // your own logic
    $this->addresses= new ArrayCollection();
}

Adding the AddressType:

class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add('state', 'text')
    ->add('city','text')
    ->add('zipcode', 'text')
    ->add('street', 'text');
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' =>  'Acme\UserBundle\Entity\Address',
    ));
}

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

to the RegistrationFormType works and the fields are displayed in the browser:

 public function buildForm(FormBuilderInterface $builder, array $options)
{
    // add your custom field
    $builder
        ->add('name')
        ->add('addresses', new AddressType())
    ;
}

But when i try to submit the form with new data, i don't know how to say symfony that the address entered should be related to the User. Im always getting the error:

"The form's view data is expected to be an instance of class Acme\UserBundle\Entity\Address, but is an instance of class Doctrine\Common\Collections\ArrayCollection. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms an instance of class Doctrine\Common\Collections\ArrayCollection to an instance of Acme\UserBundle\Entity\Address."

What am I doing wrong here?

Regards.

1

1 Answers

2
votes

you're trying to add a collection as a single field, when you give a "data_class" you're saying "here this is the form for this entity", but as the error says the system has to manage a collection of forms each one related to a single entity, you need to data transform them to something he can manage in a simple (or prebuilt) way (look for DataTransformers)

or you can use the colletion field type and pass them the address form type

-- edited after the comment --

no, sorry i've missed that, you need an entity form type because you state that a user has one address (and many user can be mapped to the same address, i.e. a family), so there's no need of a collection, though you're in the owning side persisting the user you don't have to worry, if you say cascade persist in your mapping schema for the ManyToOne relation, Doctrine will store the address for you (or use an existing one in case of a matching one)

btw i was fuzzed by your sentence "A user can have an Address, which is related OneToMany." that's misleading, a user can have an address, which is related to a ManyToOne relation (many user can have an address), the address is in a oneToMany relation with users (an address is own by many users)