Webfarmer
Webfarmer

Reputation: 263

Symfony2 Form with multiple Entities behind it

I've got the following scenario: There's a Form on my website (the creation of a usergroup) where the user needs to input several group details. Also should he be able to place an order, which is completely unrelated to the group itself (in the sense of the datamodel). This is the current code which works but only for the entity UserGroup.

$form = $this->createForm(new UserGroupType($this->get('session')), $entity, array(
    'action' => $this->generateUrl('spf_user_group_create'),
    'method' => 'POST',
));
return $form;

How would I change this (or the UserGroupType Class) to support a second entity which is not related to the UserGroup?

Upvotes: 0

Views: 55

Answers (1)

tomazahlin
tomazahlin

Reputation: 2167

Every FormType can only have one data_class.

If you need to input multiple entities in the same form, you need to make another entity class, which glues all the needed entities together.

For example, if you have a registration activation form, where user inputs data for User, Account and Location entity, you would have a class, which looks like this:

<?php

namespace Service\Bundle\UserBundle\Entity;

class RegistrationActivation
{
    /**
     * @var User
     */
    private $user;

    /**
     * @var Account
     */
    private $account;

    /**
     * @var Location
     */
    private $location;

    /**
     * @param User $user
     * @param Account $account
     * @param Location $location
     */
    public function __construct(User $user, Account $account, Location $location)
    {
        $this->user = $user;
        $this->account = $account;
        $this->location = $location;
    }

    /**
     * @return User
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * @return Account
     */
    public function getAccount()
    {
        return $this->account;
    }

    /**
     * @return Location
     */
    public function getLocation()
    {
        return $this->location;
    }

    /**
     * This is a proxy method
     * @param $boolean
     * @return $this
     */
    public function setFirstLocationDiffers($boolean)
    {
        $this->getLocation()->setFirstLocationDiffers($boolean);
        return $this;
    }

    /**
     * This is a proxy method
     * @return bool
     */
    public function getFirstLocationDiffers()
    {
        return $this->getLocation()->getFirstLocationDiffers();
    }

    /**
     * @param User $user
     * @return $this
     */
    public function setUser(User $user) {
        $this->user = $user;
        return $this;
    }

    /**
     * @param Account $account
     * @return $this
     */
    public function setAccount(Account $account) {
        $this->account = $account;
        $this->getUser()->setAccount($account);
        return $this;
    }

    /**
     * @param Location $location
     * @return $this
     */
    public function setLocation(Location $location) {
        $this->location = $location;
        $this->getUser()->addLocation($location);
        $this->getAccount()->addLocation($location);
        return $this;
    }
}

Then in your FormType, set the data_class option to 'Service\Bundle\UserBundle\Entity\RegistrationActivation' for example.

Another solution (if this turns out to complicated for your example) is to use Data Transformers.

Also, passing values to the FormType (like you do with session) through constructor is not really a good practice. Instead pass it as an option, next to action and method.

Upvotes: 1

Related Questions