php 原则-多个模型引用另一个模型中的相同id字段

hmae6n7t  于 2023-02-18  发布在  PHP
关注(0)|答案(3)|浏览(129)

我有一个文件模型,和多个(目前3)不同的其他模型(文章,工作,事件),可以都有文件,这是存储在文件模型。
问题是,当我通过CLI工具(./doctrine build-all-reload)生成表格时,我收到以下错误消息:

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot 
add or update a child row: a foreign key constraint fails 
(`my_database/articles`, CONSTRAINT `articles_id_files_target_id`
FOREIGN KEY (`id`) REFERENCES `files` (`target_id`))

文件定义为(在此定义的模型中未定义关系):

columns:
  id:
    primary: true
    autoincrement: true
    type: integer(4)
  target_id: integer(4)
  filename: string(255)
[...]

所有4种型号均具有以下关系定义:

relations:
    Files:
      type: many
      class: File
      local: id
      foreign: target_id

这是Doctrine生成的PHP代码(BaseFile.php):

public function setUp()
{
    parent::setUp();
    $this->hasOne('Publication', array(
         'local' => 'target_id',
         'foreign' => 'id'));

    $this->hasOne('Event', array(
         'local' => 'target_id',
         'foreign' => 'id'));

    $this->hasOne('Article', array(
         'local' => 'target_id',
         'foreign' => 'id'));

    $this->hasOne('Job', array(
         'local' => 'target_id',
         'foreign' => 'id'));
}

我理解 * 为什么 * 会发生这种情况(约束不能为多个表设置),但不知道如果没有多个文件表或关联表,我怎么能解决这个问题。
有没有办法告诉Doctrine它不应该在File模型中创建关系?
有什么好主意吗?

z3yyvxxp

z3yyvxxp1#

如果你想试试,
关系:

Files:
  type: many
  class: File
  local: target_id
  foreign: id
Files2:
  type: many
  class: File
  local: id
  foreign: id
os8fio9y

os8fio9y2#

您可以尝试以下操作:

columns:
    id: { type: integer(4), notnull: true, primary: true, autoincrement: true }
    target_id:  { type: integer(4), notnull: true }
    model:       { type: string, notnull: true }

Files model需要知道链接条目的id和模型,所以在Files.class.php中你也可以指定:

public function getArticles() {
    if (strcmp($this->getModel(), 'Articles')) {
        return Doctrine::getTable('Articles')->findOneById($this->getTargetId());
    } else {
        return false;
    }
}

也许有更好的方法,但是在这种情况下,你有一个表,你不需要任何更多的关系,但是你必须自己指定getter/setter,所以这取决于你的目标是否成功。

fv2wmkja

fv2wmkja3#

您可以使用Doctrine Inheritance Mapping。基本上,您需要为每个项目、作业和事件创建抽象文件实体(模型)和具体文件实体(从抽象文件实体扩展而来)。然后,每个项目、作业和事件应分别与ArticleFile、JobFile和EventFile有一对多的连接。请检查以下代码示例:

<?php
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({
 *     "article" = "ArticleFileEntity",
 *     "job" = "JobFileEntity",
 *     "event" = "EventFileEntity"
 * })
 * @ORM\Table(name="file")
 */
abstract class AbstractFile 
{
 private int $id;
}
<?php
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class ArticleFileEntity extends AbstractFileEntity 
{
}
<?php

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

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 * @ORM\Table(name="customer")
 * @package Modules\Customer\Domain\Entities
 */
class ArticleEntity 
{
     /**
     * Article file collection
     *
     * @ORM\OneToMany(targetEntity="ArticleFileEntity", cascade={"persist","remove"}, orphanRemoval=true)
     * @var Collection
     */
    protected Collection $files;
}

参考:https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/reference/inheritance-mapping.html

相关问题