Doctrine - 添加指向2个目标实体的外键

时间:2014-04-06 11:46:20

标签: php database symfony doctrine-orm foreign-keys

我有3个实体;博客,项目和评论。阻止和项目都有评论。所以我想在Comment中使用外键ref_id,它将使用ref_type值指向Blog或Project。这是我的实体

class Blog
{
  ...
  protected $id;
  ...
  protected $title;
  ...
}

class Project
{
   ...
   private $id;
   ...
   private $title;
}

class Comment
{
  ...
  protected $id;

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

  /**
   * @ORM\ManyToOne(targetEntity="**Project,Blog**", inversedBy="comments")
   * @ORM\JoinColumn(name="ref_id", referencedColumnName="id")
  */
  protected $ref_id;

 }

我是Doctrine的新手,所以它可能很简单,但可以找到解决方案。从谷歌我遇到了Mapped Superclasses但不确定它们与这个问题的关系。

1 个答案:

答案 0 :(得分:0)

是的,一个好的解决方案是继承BlogProject

准备数据库

首先,您可以制作subclass inherent by table。假设超类将被命名为“可评论”。

create table commentable( int id_commentable not null primary key auto_increment, title varchar(200) not null, c_type vachar(100) not null);

然后,每个可评论的都有自定义字段:

/* blog table */
create table blog(id_commentable int not null primary key, description text);
/* project table */
create table project(id_commentable int not null primary key, location text);

请注意,上面的三个表具有相同的主键名称。这是强制性的

评论表与可评论表

有关系
create table comments(id_comment int not null primary key auto_increment, comment text, commentable_id int not null);

创建超类和子项

根据表格,是时候开始构建实体了。

可评论的超类

/**
 * @Entity
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="c_type", type="string")
 */
abstract class Commentable
{

    /**
     * @Id
     * @Column(type="integer", nullable=false, name="id_commentable")
     * @GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @Column(type="string")
     */
    protected $title;

    /**
     * @OneToMany(targetEntity="Comment", mappedBy="commentable")
     **/
    protected $comments;

    function getComments(){ return $this->comments; }

博客

/**
 * @Entity
 * @Table(name="blog")
 */

class Blog extends Commentable{

    /**
     * @Column(type="string")
     */
    protected $title;

项目

/**
 * @Entity
 * @Table(name="project")
 */

class Project extends Commentable{

    /**
     * @Column(type="string")
     */
    protected $location;

评论

记住评论指向commentable实体,而不是其子代。

/**
 * @Entity
 * @Table(name="comments")
 */

class Comment{

    /**
     * @ManyToOne(targetEntity="Commentable", inversedBy="comments")
     * @JoinColumn(name="comment_id", referencedColumnName="id_comment")
     **/
    protected $commentable;

    /**
     * @Column(type="string")
     */
    protected $comment;

用法

例如,如果您想要项目评论,可以这样做:

// knowing id 3 is a project
$project = em->find('models\Project', 3);
$comments = $project->getComments();

或者如果您愿意,请将评论与类型无关:

$commentable = em->find('models\Commentable', 3);
$comments = $commentable->getComments();

上述两个示例都返回相同的注释列表;