问题在于:
具有属性Routing
和objectId
的班级objectType
。 objectId
是一个int,objectType
是一个字符串。这样做的原因是允许同一个表保存不同类型的路由数据。例如,Products
,Department
和Brand
的路由。因此,objectType
和objectId
的组合是我的JoinColumn。
如何与Doctrine2建立这样的双向关系?我看了一下继承的关系,但没有一个概念似乎是我正在寻找的。 p>
我可以在数据库中创建一些视图,只有几个不同的路由实体,但这似乎不是最好的路径。
以下是我的实体Department
,Product
和Brand
。
../Entity/Department.php
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity()
* @ORM\Table(name="departments")
*/
class Department implements DescribableInterface
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer", length=11)
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="status", type="string", length=1)
*/
private $status;
/**
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
...
../Entity/Product.php
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="products")
*/
class Product implements DescribableInterface
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer", length=11)
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="status", type="string", length=1)
*/
private $status;
/**
* @ORM\Column(name="product_code", type="string", length=100, nullable=true)
*/
private $productCode = '';
/**
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
...
../Entity/Brand.php
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="brands")
*/
class Brand
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer", length=11)
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="status", type="string", length=1)
*/
private $status = 'a';
/**
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
...
每个产品,品牌和部门都有自己的网址,该网址由object_type
和object_id
设置的路由表中保存,其中object_type
只是department
,{ {1}}或product
和brand
是相应产品,品牌或部门的唯一ID。
object_id
../Entity/Routing.php
我真正感到困难的是如何设置关系,因此部门,产品和品牌可以从单个路由实体访问其URL。
我尝试将关系添加到use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="routing")
*/
class Routing
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer", length=11)
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="object_id", type="integer", length=11)
*/
private $objectId;
/**
* @ORM\Column(name="object_type", type="string", length=100)
*/
private $objectType;
/**
* @ORM\Column(name="url", type="text")
*/
private $url;
...
,但似乎不喜欢这样。是否可以这样设置?
我基本上想要实现的是获取数据对象并能够获取对象的URL,例如:
$objectId
有人可以帮忙吗?
答案 0 :(得分:4)
经过进一步的研究,我发现一个人(Dirk Olbertz)知道谁有同样的问题。
可在以下网址找到相关信息:Google Groups: Multiple JoinColumns?
我现在已经实现了这一点,我将解释我是如何做到这一点的,这可能对其他人有帮助。
我的问题的答案是使用单表继承。
我需要做的第一件事是更新routing
实体以使用单表继承:
../Entity/Routing.php
/**
* @ORM\Entity
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="object_type", type="string")
* @ORM\DiscriminatorMap({"product" = "ProductRouting", "department" = "DepartmentRouting", "brand" = "BrandRouting"})
* @ORM\Table(name="routing")
*/
class Routing
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer", length=11)
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
...
DiscriminatorColumn
允许我指定用于链接的列,在本例中为object_type
字段。
DiscriminatorMap
允许我指定object_type
将与哪些实体相关联。
然后必须创建这些实体以扩展Routing
实体。
../Entity/ProductRouting.php
/**
* @ORM\Entity
*/
class ProductRouting extends Routing
{
/**
* @ORM\ManyToOne(targetEntity="Product")
* @ORM\JoinColumn(name="object_id", referencedColumnName="id")
*/
protected $product;
...
../Entity/DepartmentRouting.php
/**
* @ORM\Entity
*/
class DepartmentRouting extends Routing
{
/**
* @ORM\ManyToOne(targetEntity="Department")
* @ORM\JoinColumn(name="object_id", referencedColumnName="id")
*/
protected $department;
...
../Entity/BrandRouting.php
/**
* @ORM\Entity
*/
class BrandRouting extends Routing
{
/**
* @ORM\ManyToOne(targetEntity="Brand")
* @ORM\JoinColumn(name="object_id", referencedColumnName="id")
*/
protected $brand;
...
然后,在每个Product
,Department
和Brand
个实体中,我需要添加新的$routings
。
../Entity/Product.php
...
class Product
{
...
/**
* @ORM\OneToMany(targetEntity="ProductRouting", mappedBy="product", cascade={"all"})
*/
private $routings;
...
../Entity/Department.php
...
class Department
{
...
/**
* @ORM\OneToMany(targetEntity="DepartmentRouting", mappedBy="department", cascade={"all"})
*/
private $routings;
...
../Entity/Brand.php
...
class Brand
{
...
/**
* @ORM\OneToMany(targetEntity="BrandRouting", mappedBy="brand", cascade={"all"})
*/
private $routings;
...
希望有帮助...