Dai*_*mos 2 symfony doctrine-orm
我想创建带有分类词汇表的 Tag 实体类,它将被多个实体使用。有没有可能,用三列创建多条关系?我需要存储标签 id、实体 id 和实体类名。
所以我现在有:
<?php
/**
* Taxonomy
*
* @ORM\Table(
* name="tag_taxonomy",
* indexes={
* @ORM\Index(name="tag_taxonomy_namex", columns={"name"})
* }
* )
* @ORM\HasLifecycleCallbacks
* @ORM\Entity
*/
class Taxonomy
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
* @ORM\Column(name="name", type="string", length=50)
*/
protected $name;
/**
* @ORM\OneToMany(targetEntity="Tag", mappedBy="taxonomy", fetch="LAZY")
*/
protected $tags;
// .....
}
Run Code Online (Sandbox Code Playgroud)
标签表:
<?php
/**
* Tag
*
* @ORM\Table(
* name="tag",
* indexes={
* @ORM\Index(name="namex", columns={"name"})
* }
* )
* @ORM\HasLifecycleCallbacks
* @ORM\Entity
*/
class Tag
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
protected $id;
/**
* @var string
* @ORM\Column(name="name", type="string", length=50)
*/
protected $name;
/**
* @ORM\ManyToOne(targetEntity="Taxonomy", inversedBy="tags", fetch="LAZY")
* @ORM\JoinColumn(name="taxonomy_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected $taxonomy;
// ....
}
Run Code Online (Sandbox Code Playgroud)
关系表:
<?php
/**
* @ORM\Table(
* name="tag_tagging",
* uniqueConstraints={
* @ORM\UniqueConstraint(name="tagging_idx", columns={"tag_id", "entity_name", "record_id"})
* },
* indexes={
* @ORM\Index(name="entity_name_idx", columns={"entity_name", "record_id"})
* }
* )
* @ORM\HasLifecycleCallbacks
* @ORM\Entity
*/
class Tagging
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="Tag", inversedBy="tagging", cascade="ALL")
* @ORM\JoinColumn(name="tag_id", referencedColumnName="id", onDelete="CASCADE")
**/
protected $tag;
/**
* @var string
* @ORM\Column(name="entity_name", type="string", length=100)
*/
protected $entityName;
/**
* @var int
* @ORM\Column(name="record_id", type="integer")
*/
protected $recordId;
// .....
}
Run Code Online (Sandbox Code Playgroud)
所以我已经有 3 列作为键的关系表:“tag_id”、“entity_name”、“record_id”。现在知道如何与任何实体创建关系以标记表吗?也许根本不需要标记实体?
我想知道为任何实体类型创建标签实体的最佳方法是什么。所以我可以为用户、文章或任何东西使用标签。当然,可以有许多关系为每个实体创建单独的关系表,对吗?但方法正确吗?
即使它不允许在任何实体和Tagging
类之间创建真正的关联(具有基础外键),您的方法也完全正确。不过,这完全可以接受。您需要一种方法来定义将进入您的entityName
领域的内容,以便它可以有效地充当鉴别器领域。
正如您所说,您还可以为每个可以标记的实体创建一个单独的连接表。这是我目前在我的一个项目中使用的解决方案,它也运行良好。最后,这取决于您希望能够轻松执行的操作。
Tagging
表/实体您选择的这种方法也是FPNTagBundle中介绍的方法,它集成了自己的DoctrineExtensions-Taggable库。它依赖于一个Tagging
实体,该实体是ManyToOne
与您的Tag
表的关联的拥有方,并拥有两个字段 (resourceId
和resourceType
) 来引用标记的实体。
如果您想沿着这条路走下去,我建议您查看 FPNTagBundle 的 Taggable 原则扩展实现。或者,您可以查看其他可标记的扩展名。它非常相似,但它以不同的方式使用学说事件来处理保存/加载。
优点:
Tag
可以在它与 Tagging
缺点:
Tag
或Tagging
Tagging
和您的实体之间的关系没有外键,因此您的应用程序必须处理孤立Tagging
条目的删除(无法依赖于ON DELETE CASCADE
)tags
如果您希望在实体中使用其结果,则必须手动处理其结果才能正确地填充您的字段。ManyToMany
由每个加标签实体所有的关联使用这种方法,您最终会为每个声明ManyToMany
与您的Tag
实体的关联的实体创建一个连接表。为了快速向实体添加标签,我个人使用TaggableTrait
这样的标签 :
trait TaggableTrait
{
/** @ORM\ManyToMany(targetEntity="AppBundle\Entity\Tag\Tag") */
private $tags;
/* ... getter and add/remove methods ... */
}
Run Code Online (Sandbox Code Playgroud)
这样,通过use TaggableTrait
我的实体中的简单语句,我可以启用标记。
优点:
缺点:
Tag
在反面,你需要ManyToMany
为每个 Taggable 实体添加关联的反面无论如何,正如我在开始时所说的,这一切都归结为您想对标签执行什么样的操作。与两个字段resourceId
和实体resourceType
内部的通用关系Tagging
可能会给您的应用程序内部带来更多的灵活性,但在处理某些事情的原则时,使用它也会有点棘手。
归档时间: |
|
查看次数: |
1226 次 |
最近记录: |