问题描述
问题来了:
Class Routing
具有属性 objectId
和 objectType
.objectId
是一个整数,objectType
是一个字符串.这样做的原因是允许同一个表保存不同类型路由的数据.例如对于Products
、Department
和Brand
的路由.所以,objectType
和 objectId
的组合就是我的 JoinColumn.
如何与 Doctrine2 建立这种双向关系?我查看了继承关系,但似乎没有一个概念是我正在寻找的.p>
我可以在数据库中创建一些视图,并且只有几个不同的路由实体,但这似乎不是最好的路由.
这是我的实体 Department
、Product
和 Brand
.
../Entity/Department.php
使用 Doctrine\ORM\Mapping 作为 ORM;/*** @ORM\Entity()* @ORM\Table(name="部门")*/类 Department 实现了 DescribableInterface{/*** @ORM\Id* @ORM\Column(name="id", type="integer", length=11)* @ORM\GeneratedValue(strategy="AUTO")*/私人 $id;/*** @ORM\Column(name="status", type="string", length=1)*/私人 $status;/*** @ORM\Column(name="name", type="string", length=255)*/私人 $name;...
../Entity/Product.php
使用 Doctrine\ORM\Mapping 作为 ORM;/*** @ORM\实体* @ORM\Table(name="products")*/类 Product 实现了 DescribableInterface{/*** @ORM\Id* @ORM\Column(name="id", type="integer", length=11)* @ORM\GeneratedValue(strategy="AUTO")*/私人 $id;/*** @ORM\Column(name="status", type="string", length=1)*/私人 $status;/*** @ORM\Column(name="product_code", type="string", length=100, nullable=true)*/私人 $productCode = '';/*** @ORM\Column(name="name", type="string", length=255)*/私人 $name;...
../Entity/Brand.php
使用 Doctrine\ORM\Mapping 作为 ORM;/*** @ORM\实体* @ORM\Table(name="brands")*/班级品牌{/*** @ORM\Id* @ORM\Column(name="id", type="integer", length=11)* @ORM\GeneratedValue(strategy="AUTO")*/私人 $id;/*** @ORM\Column(name="status", type="string", length=1)*/私人 $status = 'a';/*** @ORM\Column(name="name", type="string", length=255)*/私人 $name;...
每个产品、品牌和部门都有自己的 URL,该 URL 保存在由 object_type
和 object_id
设置的路由表中,其中 object_type
只是department
、product
或brand
并且object_id
是相应产品、品牌或部门的唯一ID.
../Entity/Routing.php
使用 Doctrine\ORM\Mapping 作为 ORM;/*** @ORM\实体* @ORM\Table(name="路由")*/类路由{/*** @ORM\Id* @ORM\Column(name="id", type="integer", length=11)* @ORM\GeneratedValue(strategy="AUTO")*/私人 $id;/*** @ORM\Column(name="object_id", type="integer", length=11)*/私人 $objectId;/*** @ORM\Column(name="object_type", type="string", length=100)*/私人 $objectType;/*** @ORM\Column(name="url", type="text")*/私人 $url;...
我真正苦恼的是如何建立关系,以便部门、产品和品牌可以从单个路由实体访问其 URL.
我尝试将关系添加到 $objectId
,但它似乎不喜欢那样.可以这样设置吗?
我基本上想要实现的是获取数据对象并有能力获取对象的URL,例如:
$departments = $em->getRepository("AdamStaceySiteBundle:Department")->findAll();foreach ($departments 作为 $department){echo '<a href="'.$department->getUrl().'">'.$department->getMenuTitle().'</a>;}
有人可以帮忙吗?
经过进一步研究后,我发现一位知情人士 (Dirk Olbertz) 遇到了同样的问题.
信息可在以下位置找到:Google 网上论坛:多个 JoinColumns?
我现在已经实现了这个,我将解释我是如何做到的,因为它可能会帮助其他人.
我的问题的答案是使用单表继承.
我需要做的第一件事是更新 routing
实体以使用单表继承:
../Entity/Routing.php
/*** @ORM\实体* @ORM\InheritanceType("SINGLE_TABLE")* @ORM\DiscriminatorColumn(name="object_type", type="string")* @ORM\DiscriminatorMap({"product" = "ProductRouting", "department" = "DepartmentRouting", "brand" = "BrandRouting"})* @ORM\Table(name="路由")*/类路由{/*** @ORM\Id* @ORM\Column(name="id", type="integer", length=11)* @ORM\GeneratedValue(strategy="AUTO")*/私人 $id;...
DiscriminatorColumn
允许我指定将用于链接的列,在本例中是 object_type
字段.
DiscriminatorMap
允许我指定什么 object_type
将与什么实体链接.
然后必须创建这些实体来扩展 Routing
实体.
../Entity/ProductRouting.php
/*** @ORM\实体*/类 ProductRouting 扩展了路由{/*** @ORM\ManyToOne(targetEntity="Product")* @ORM\JoinColumn(name="object_id", referencedColumnName="id")*/受保护的 $product;...
../Entity/DepartmentRouting.php
/*** @ORM\实体*/类 DepartmentRouting 扩展了路由{/*** @ORM\ManyToOne(targetEntity="部门")* @ORM\JoinColumn(name="object_id", referencedColumnName="id")*/受保护的$部门;...
../Entity/BrandRouting.php
/*** @ORM\实体*/BrandRouting 类扩展了路由{/*** @ORM\ManyToOne(targetEntity="品牌")* @ORM\JoinColumn(name="object_id", referencedColumnName="id")*/受保护的 $brand;...
然后在每个 Product
、Department
和 Brand
实体中,我需要添加新的 $routings
.
../Entity/Product.php
...产品类别{.../*** @ORM\OneToMany(targetEntity="ProductRouting",mappedBy="product",cascade={"all"})*/私人$路由;...
../Entity/Department.php
...班级部{.../*** @ORM\OneToMany(targetEntity="DepartmentRouting",mappedBy="department",cascade={"all"})*/私人$路由;...
../Entity/Brand.php
...班级品牌{.../*** @ORM\OneToMany(targetEntity="BrandRouting",mappedBy="brand",cascade={"all"})*/私人$路由;...
希望有帮助...
Here is the problem:
Class Routing
with attributes objectId
and objectType
. objectId
is an int, and objectType
is a string. The reason for this was to allow the same table to hold data for different kind of routings. For instance for the routing of Products
, Department
and Brand
. So, the combination of the objectType
and the objectId
is my JoinColumn.
How do I create such a bidirectional relationship with Doctrine2? I looked at inherited relationships, but none of the concepts seemed to be what I'm looking for.
I could create some views in the database and just have a couple of different Routing entities, but this does not seem the best route.
Here are my entities Department
, Product
and 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;
...
Each product, brand and department has its own URL that is held in the routing table set by the object_type
and object_id
where the object_type
is simply department
, product
or brand
and the object_id
is the unique id of the corresponding product, brand or department.
../Entity/Routing.php
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;
...
What I am really struggling with is how do I setup the relationship, so the departments, products and brands can access their URL from the single routing entity.
I have tried adding the relationships to the $objectId
, but it doesn't seem to like that. Is it possible to set this up like this?
What I am basically trying to achieve is to get the data object and have the ability to get the URL of an object, for example:
$departments = $em->getRepository("AdamStaceySiteBundle:Department")->findAll();
foreach ($departments as $department)
{
echo '<a href="'.$department->getUrl().'">'.$department->getMenuTitle().'</a>;
}
Can anyone help?
After further researching I found a man (Dirk Olbertz) in the know who had the same problem.
Information can be found at: Google Groups: Multiple JoinColumns?
I have now implemented this and I will explain how I did it incase it might help anyone else.
The answer to my problem was the use of single table inheritance.
The first thing I needed to do was update the routing
entity to use single table inheritance:
../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;
...
The DiscriminatorColumn
allowed me to specify what column would be used to link, which in this case was the object_type
field.
The DiscriminatorMap
allowed me to specify what object_type
will link with what entities.
These entities then had to be created that extended the Routing
entity.
../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;
...
Then in each of the Product
, Department
and Brand
entities I needed to add the new $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;
...
Hope that helps...
这篇关于Symfony2 中使用 Doctrine 注释的多个 JoinColumns?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!