Symfony 2 Doctrine一对多关系未写入连接表

3

我正在尝试创建一个tax_ratescountries之间的一对多关系,其中一个税率可以与多个国家相关联,并在参考以下模式的国家上使用连接表引用税率:

/** @Entity **/
class TaxRates
{
    ...

    /**
    * @ORM\OneToMany(targetEntity="Acme\DemoBundle\Entity\Country", mappedBy="tax_rate", cascade={"persist"})
    */
    protected $country;

    ...

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

/** @Entity **/
class Country
{
    /**
      * @ORM\ManyToOne(targetEntity="Acme\TaxBundle\Entity\TaxRates", inversedBy="country")
      * @ORM\JoinColumn(name="taxrate_id", referencedColumnName="id")
      */
    protected $tax_rate;
}

我在Symfony表单中使用了TaxRates,其中包括国家作为实体类型的一部分。
$builder->add('country', 'entity', array(
                'class' => "AcmeDemoBundle:Country",
                'property' => "name",
                "multiple" => true,
            ))

当我载入表单,输入有效数据并提交时,它会正确写入TaxRates表。然而它没有将ID添加到与国家相关联的联接表中,因此我有一条记录,没有任何引用它的内容。
如果有人能够指导我做错了什么,那就太好了,谢谢。

1
为什么要有一个连接表?你的国家实体是多对一的。这意味着一个税率可以与一个或多个国家相关联。如果一个国家可以拥有一个或多个税率,那么你需要一个多对多关系。 - Hakim
@Hakim 我正在使用Doctrine文档中所述的联接表:http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-bidirectional - 它是一个税率对应多个国家,不能是多对多。 - Sharpy310
例如,如果您从英国向欧盟的任何国家运送货物,您必须按20%的费率收费 - 因此将有多个国家适用于同一费率。 - Sharpy310
抱歉,我不是很理解。在您的示例中,我理解当您提交表单时,会在tax_rate中插入一行,在country中插入一个或多个行。每行国家都应该有tax_rate_id对吧?您的问题是国家行的tax_rate_id设置为null吗? - Hakim
@Hakim 是的,基本上当表单被提交时,它会创建一个tax_rate记录,然后应该获取该记录的id,并在countries表中将所有与该id相关联的国家添加到joincolumn(taxrate_id)中 - 如果有点混淆,请见谅。 - Sharpy310
显示剩余2条评论
1个回答

0

这只是一个猜测,但我怀疑您没有调用$country->setTaxRate。请尝试执行以下操作:

class TaxRates {
  function addCountry($country) {
    $this->countries[] = $country;
    $country->setTaxRate($this); // This is what might be missing

我们对于任何其他关联都是这样做的,但在上面的例子中,我在这个函数中添加了一个var_dump();exit;,但它没有触发 - 所以我唯一的想法是它没有完全调用这个函数。 - Sharpy310
好的。我会删除答案,因为那只是一个猜测。嗯,你发布的代码中有一些@Entitys而不是@ORM/Entity。是复制粘贴错误吗?也许你在AcmeDemoBundle\Resources\config\doctrine下有一些旧的映射文件?如果是这样,那么你的注释将被忽略。 - Cerad
/** @Entity **/以及所有的Acme/Demo等等...只是一个占位符,以便保持文件路径的私密性,因为它包含公司名称等信息。所有的文件路径都连接在一起并且正确,这是有效的代码。 - Sharpy310
足够了。只要您确定您的实际代码使用@ORM\Entity而不是@Entity,那么我就没有更多的想法了。 - Cerad
我们也可以通过控制器显式地处理请求,并手动将其硬编码以使其工作 - 但是这肯定应该通过Doctrine基本工作?- 不管怎样,感谢您的查看。 - Sharpy310
"手动硬编码"有点令人担忧。我想您可以使用控制器操作代码更新您的问题。我假设您遵循通常模式而不做任何奇怪的事情?国家表是您所谓的"联接表"吗?您只有两个表,对吗?" - Cerad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接