mhoff
mhoff

Reputation: 31

Symfony2.1 Embedded Forms and Foreign Key Relations

I decided to completely rephrase my question. Hopefully my issue is much clearer this way.

How do you embed forms that represent a foreign key field within an entity? For example, a Property has a foreign key to a table of Statuses (Owned, Available, For Sale, etc...). Using embedded forms, I'm unsure how to have my embedded form (in this case Status) understand what parent entity is embedding it so that when the form is submitted, creating/changing the Status on a Property only changes the foreign key relation. I'm able to query a property and change its status by calling $property->setStatus($status) just fine so I believe my Doctrine relationships are correct.

Right now, I receive this error when trying to change a status on form submit:

Catchable Fatal Error: Object of class Test\Bundle\SystemBundle\Entity\Status could not be converted to string in /home/vagrant/projects/test.dev/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php line 1118 

My form creation:

$form = $this->createForm(new PropertyType(), $property);

The entity relation of Property to Status in my Property entity:

/**
 * @var Status $status
 *
 * @ORM\ManyToOne(targetEntity="Test\Bundle\SystemBundle\Entity\Status")
 * @ORM\JoinColumn(name="StatusId", referencedColumnName="Id", nullable=false)
 */
protected $status;

Here is the line in my PropertyType class that embeds the StatusType class:

->add('status', new StatusType())

And here is my StatusType form class:

class StatusType extends AbstractType
{
public $statusType = null;

public function __construct($statusType)
{
    $this->statusType = $statusType;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{

    $builder->add('name', 'entity', array('label' => 'Status Name',
            'class'     => 'Test\Bundle\SystemBundle\Entity\Status',
            'property'  => 'name'));

}

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

public function getDefaultOptions(array $options)
{
    return array('data_class' => 'Test\Bundle\SystemBundle\Entity\Status');
}

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

Upvotes: 0

Views: 2451

Answers (2)

mhoff
mhoff

Reputation: 31

One solution I have found is to put all of the logic on PropertyType for the status.

->add('status', 'entity',
            array('class'   => 'Test\Bundle\SystemBundle\Entity\Status',
                'property'  => 'name',
                'query_builder' => function(EntityRepository $er){
                    return $er->createQueryBuilder('status')
                    ->orderBy('status.name', 'ASC');
                }))

Instead of embedding a StatusType:

->add('status', new StatusType())

I don't like this method because every entity that uses Status will have this duplicated but it works for the time being until I figure out how to get it to work.

Upvotes: 0

Adrian Schneider
Adrian Schneider

Reputation: 7449

Without seeing your Status entity, it sounds like you need to add a __toString() method to it. In order for Symfony to render the entity as text, it needs to know what to display. Something like this...

class Status
{    
    public $title;

    public function __toString()
    {
        return $this->title;
    }
}

Upvotes: 1

Related Questions