【问题标题】:Symfony2 : Many-To-Many with a custom link tableSymfony2:带有自定义链接表的多对多
【发布时间】:2012-03-20 15:42:11
【问题描述】:

我正在处理一个包含 3 个实体的表单:

  • 订单(idorder)
  • 支持参考表 (idsupport)
  • 链接表(idorder、idsupport)

当我尝试选择一个或多个支持时,我收到了这个错误:

Catchable Fatal Error: Argument 1 passed to Myapp\MyBundle\Entity\PcastCmdsupports::setIdsupports() must be an instance of Myapp\MyBundle\Entity\PcastSupports, instance of Doctrine\Common\Collections\ArrayCollection given, 
called in C:\wamp\www\php\Symfony\vendor\symfony\src\Symfony\Component\Form\Util\PropertyPath.php on line 347 and defined in C:\wamp\www\php\Symfony\src\Myapp\MyBundle\Entity\PcastCmdsupports.php line 62 

因为我已经创建了我在网上看到的链接表,所以我可以在我的链接表中简单地创建 2 个多对一关系:

/**
 * @var PcastSupports
 *
 * @ORM\ManyToOne(targetEntity="PcastSupports")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="IDSUPPORTS", referencedColumnName="IDSUPPORTS")
 * })
 */
private $idsupports;

/**
 * @var PcastOrder
 *
 * @ORM\ManyToOne(targetEntity="PcastOrder")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="IDORDER", referencedColumnName="IDORDER")
 * })
 */
private $idorder;

还有我的 setter 和 getter:

/**
 * Set idsupports
 *
 */
public function setIdsupports(\Myapp\MyBundle\Entity\PcastSupports $idsupports)
{
    $this->idsupports = $idsupports;
}

/**
 * Get idsupports
 *
 */
public function getIdsupports()
{
    return $this->idsupports;
}

/**
 * Set idorder
 *
 */
public function setIdcommande(\Myapp\MyBundle\Entity\PcastOrder $idorder)
{
    $this->idorder = $idorder;
}

/**
 * Get idorder
 *
 */
public function getIdorder()
{
    return $this->idorder;
}

在我的订单中,我可以选择一个或多个支架,所以我创建了这样的表格:

$form_clips = $this->createFormBuilder($cmdclips)
->add('idorder', new CmdsupportsType)
->getForm();

最后是我的 supportsType 表单:

$builder
    ->add('idsupports', 'entity', array(
    'class'         => 'MyappMyBundle:PcastSupports', 
    'property'      => 'name',
    'expanded'      => true,
    'multiple'      => true,
    'query_builder' => function(EntityRepository $er) 
    {
        return $er->createQueryBuilder('pts')
        ->orderBy('pts.idsupports','ASC');
    },
));

我没有使用任何 arraycollection,所以我不明白这个问题。在此操作期间发生了问题:

$form_clips->bindRequest($request);

非常感谢您的帮助!


我试图在一个简单的案例(用户、公司和 user_company 实体)中使其与多对多关系一起工作,但是当我尝试向用户添加公司时遇到问题:

Warning: oci_bind_by_name() [<a href='function.oci-bind-by-name'>function.oci-bind-by-name</a>]: Invalid variable used for bind in C:\wamp\www\php\Promocast\Symfony\vendor\doctrine-dbal\lib\Doctrine\DBAL\Driver\OCI8\OCI8Statement.php line 113

我在谷歌上搜索了很多,但我没有找到任何关于此错误的信息...根据堆栈跟踪,错误是当学说尝试添加公司对象时:

array('column' => ':param10', 'variable' => object(PcastCompany), 'type' => '1')

我的用户实体(societe = 公司):

/**
 * @ORM\ManyToMany(targetEntity="PcastSociete", inversedBy="users")
 * @ORM\JoinTable(name="PcastLienusersociete",
 *   joinColumns={@ORM\JoinColumn(name="ImUser_iduser", referencedColumnName="iduser")},
 *   inverseJoinColumns={@ORM\JoinColumn(name="PcastLienusersociete_idsociete", referencedColumnName="idsociete")}
 * )
 */
private $societes;

public function getSocietes()
{
    return $this->societes;
}

public function addSociete(\Myapp\MyBundle\Entity\PcastSociete $societe)
{
    $this->societes[] = $societe;
}

我的公司实体:

/**
 * @ORM\ManyToMany(targetEntity="ImUser", mappedBy="societes")
 */
private $users;

public function __construct() {
    $this->users = new \Doctrine\Common\Collections\ArrayCollection();
}

如果有人有任何想法......

谢谢

【问题讨论】:

标签: php forms symfony doctrine-orm


【解决方案1】:

您不应该有代表链接表的实体。如果您正确注释了两个实体,Doctrine 将自行处理链接表的创建。

此外,您首先不需要任何链接表来建立多对一关系,您要做的是在两个实体中使用多对多注释。

http://readthedocs.org/docs/doctrine-orm/en/latest/reference/association-mapping.html?highlight=many%20to%20one#many-to-many-bidirectional

【讨论】:

  • 好吧,我试试,问一个问题,教义是如何创建这个链接表的? (在数据库中还是像实体一样?)感谢您的回答!
  • 在多对多注释中,您必须提供要用作链接表的表的名称。如果它已经存在,它将直接使用它,如果它不存在,它将在数据库中创建表并从这里开始使用它。
【解决方案2】:

从基础开始。我对有关 ManyToMany 的其他事情感到好奇,所以我抓住了您的实体作为测试用例。在深入研究表单等之前,请确保您可以从命令行执行一个简单的测试用例,例如:

use Zayso\ArbiterBundle\Entity\PcastSociete as Company;
use Zayso\ArbiterBundle\Entity\ImUser       as User;

protected function test1()
{
    $em = $this->getContainer()->get('doctrine.orm.entity_manager');
    $company = new Company();
    $em->persist($company);

    $user = new User();
    $user->addSociete($company);
    $em->persist($user);

    $em->flush();

}

对于我使用的实体:

namespace Zayso\ArbiterBundle\Entity;

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

/**
 * @ORM\Entity
 */
class ImUser
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer",name="iduser") 
 * @ORM\GeneratedValue
 */
protected $id;

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

/**
 * @ORM\ManyToMany(targetEntity="PcastSociete", inversedBy="users")
 * @ORM\JoinTable(name="PcastLienusersociete",
 *   joinColumns={@ORM\JoinColumn(name="ImUser_iduser", referencedColumnName="iduser")},
 *   inverseJoinColumns={@ORM\JoinColumn(name="PcastLienusersociete_idsociete", referencedColumnName="idsociete")}
 * )
 */
private $societes;

public function getSocietes()
{
    return $this->societes;
}

public function addSociete(PcastSociete $societe)
{
    $this->societes[] = $societe;
}
public function __construct() 
{
    $this->societes = new ArrayCollection();
}

}

namespace Zayso\ArbiterBundle\Entity;

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

/**
 * @ORM\Entity
 */
class PcastSociete
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer", name="idsociete") 
 * @ORM\GeneratedValue
 */
protected $id;

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

/**
 * @ORM\ManyToMany(targetEntity="ImUser", mappedBy="societes")
 */
private $users;

public function __construct() 
{
    $this->users = new ArrayCollection();
}
}

完成上述工作,然后我们可以继续解决表单问题。

【讨论】:

  • 感谢您的回答,我没有说,但我的测试实际上和您的一样。我只是使用一个表单来填写我的用户实体,然后手动添加一个公司:$test_societe = $em->getRepository('MyappMyBundle:PcastSociete')->find(49); $newUser->addSociete($test_societe); 然后只是保留用户,这就是为什么我不理解 symfony 错误
  • 不知道有什么建议,除非可能使用 mysql 数据库进行测试。 PcastCompany(根据您的错误)有点可疑。会期待像 PcastSociete 这样的东西。并且设置一个小测试环境,以便您可以从命令行运行,将来会为您节省大量精力。
  • 好的,我尝试使用另一个示例,问题是每次我尝试在 setter 中使用对象持久化实体时都会收到此错误 (Warning: oci_bind_by_name())。就像教义不明白他必须在坚持时只取这个对象的id。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-11
  • 1970-01-01
  • 1970-01-01
  • 2022-09-27
相关资源
最近更新 更多