質問

There is a one-to-one relationship between User and Company entity.
When initializing (creating) the user's company, userID should be bind to Company user field as a foreign key. But instead of that, i get this error message:

Property "id" is not public in class "Website\CompanyBundle\Entity\User". Maybe you should create the method "setId()"?

Why Symfony wants to create new User when this form is about Company entity, and User entity is just a collection that should provide user's ID.

Here is my code:

Company.php entity:

namespace Website\CompanyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity(repositoryClass="Website\CompanyBundle\Entity\Repository\CompanyRepository")
 * @ORM\Table(name="company")
 */
class Company
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

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

    /**
     * @ORM\Column(type="string")
     */
    protected $name;

}


CompanyType.php

class CompanyType extends AbstractType
{
    private $security;
    public function __construct(SecurityContext $security)
    {
        $this->security= $security;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $user = $this->securityContext->getToken()->getUser();

        $builder
        ->add('user', new UserType($security))
        ->add('company_name')
        ->add('company_address')
        ...
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Website\CompanyBundle\Entity\Company'
        ));
    }

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


UserRelationType.php

class UserRelationType extends AbstractType
{
    private $user;

    public function __construct(SecurityContext $security){
        $this->user = $security->getToken()->getUser();
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('id', 'hidden', array('data' => $this->user->getId()))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Website\CompanyBundle\Entity\User'
        ));
    }

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


User.php entity

namespace Website\CompanyBundle\Entity;

use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string")
     */
    protected $name;

    /**
     * @ORM\OneToOne(targetEntity="Company", mappedBy="user")
     */
    protected $company;
}
役に立ちましたか?

解決

You map entity to form in UserRelationType. On save it try to set id on user entity. You must specify data transformer or use entity type if you need to select existed user.

If you want to set current user, better do it in event listener like pre_persist

他のヒント

your properties in your entities are protected but you have not created getters/setters for them. ( or you have not pasted your full code )

Therefore the form-builder is not able to access your user's properties.

At least the public function setId($id) in User.php is definitely missing!

That's why the exception is thrown saying:

Maybe you should create the method "setId()"?

Create getters and settes for every property using ...

app/console doctrine:generate:entities

or create them by hand...

User.php

public function getId()
{
    return $this->id;
}

public function setId($id)
{
    $this->id = $id;
    return $this;
}

// ...

I solved this problem without adding collections and just using Doctrine transitive persistence like described in this page: https://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations

CompanyController.php

public function createIndex(Request $request){
    $user = $this->getId();
    $company = new Company();

    if($user instanceof User){
        $company->setUser($user);
    }

    $request = $this->getRequest();
    $createForm = $this->createForm(new CompanyType(), $company);

    if('POST' === $request->getMethod())
    {
        $createForm->bindRequest($request);

        if($createForm->isValid())
        {
            $em = $this->getDoctrine()->getManager();
            $em->persist($company);
            $em->flush();
        }
    }
}



Thank you all for your help

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top