【问题标题】:Symfony2: Inserting collection form dataSymfony2:插入集合表单数据
【发布时间】:2013-06-12 21:19:06
【问题描述】:

UserCompany 实体之间存在一对一的关系。
初始化(创建)用户的公司时,用户 ID 应作为外键绑定到公司用户字段。但不是那样,我收到以下错误消息:

属性“id”在类中不公开 “网站\CompanyBundle\实体\用户”。也许你应该创建 方法“setId()”?

当这个表单是关于公司实体的时候,为什么 Symfony 想要创建新用户,而用户实体只是一个应该提供用户 ID 的集合。

这是我的代码:

Company.php 实体

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';
    }
}


用户关系类型.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 实体

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;
}

【问题讨论】:

  • 请提供您的用户实体
  • 添加了 User 实体,只是一个普通的 User 类,具有一对一的关系
  • 您缺少 getter/setter,请查看我的答案以解决此问题。

标签: symfony symfony-forms symfony-components


【解决方案1】:

您将实体映射到UserRelationType 中的表单。保存时尝试在用户实体上设置 id。如果需要选择现有用户,则必须指定data transformer 或使用entity type

如果你想设置当前用户,最好在pre_persist这样的事件监听器中设置

【讨论】:

  • 绝对有价值的信息,我昨晚在床上回忆了“实体字段类型”的解决方案,但是 prePersist 似乎是解决这个问题的正确解决方案(希望我能做对)跨度>
  • 是的,被遗忘的人在这里提供了很好的信息,真的......您已经按照我之前建议的解决方案修复了丢失的二传手,对吧?
【解决方案2】:

您的实体中的属性受到保护,但您尚未为它们创建 getter/setter。 (或者你还没有粘贴你的完整代码)

因此,表单构建器无法访问您用户的属性。

至少 User.php 中的public function setId($id) 肯定不见了!

这就是抛出异常的原因:

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

使用 ... 为每个属性创建 getter 和 settes

app/console doctrine:generate:entities

或手动创建它们...

用户.php

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

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

// ...

【讨论】:

    【解决方案3】:

    我在不添加集合的情况下解决了这个问题,只使用了本页中描述的 Doctrine 传递持久性: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();
            }
        }
    }
    



    谢谢大家的帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多