Reputation: 539
I have some entity classes which I want to share some common aspects. I have MagazineEntity and PublisherEntity. I want them to have, for example, a collection of links to other websites (the Magazine official page, it's wikipedia entry and some newssites referencing it, for example, and similarly for the Publisher).
To store those Links, since there would be many of them related to each entity, I thougth that I should create a OneToMany relationship from the Magazine with a new LinkEntity. But that would make it necesary to create another entity class for a PublisherLink, since the first LinkEntity would store the ID from the Magazine, that could be the same as a Publisher ID or a Issue ID. If not, this is what I would have:
Magazine: [ID: 1]
LinkEntity: [ID: 1, Link: http://MagazineWebsite/, RelatedID: 1]
LinkEntity: [ID: 3, Link: http://MagazineWebsite2/, RelatedID: 1]
LinkEntity: [ID: 4, Link: http://MagazineWebsite3/, RelatedID: 1]
LinkEntity: [ID: 7, Link: http://MagazineWebsite4/, RelatedID: 1]
So, if I use the same LinkEntity with a Publisher, It would store this:
Publisher: [ID: 1]
LinkEntity: [ID: 2, Link: http://PublisherWebsite/, RelatedID: 1]
LinkEntity: [ID: 5, Link: http://PublisherWebsite2/, RelatedID: 1]
LinkEntity: [ID: 6, Link: http://PublisherWebsite3/, RelatedID: 1]
So, when retrieving, I would end with all of them, since they aren't differentiated, but I want just the ones referencing my actual entity (be it a Publisher or a Magazine). The easy way should be then to add another field, like "RelatedType", which let me with the problem that I wouldn't know how to retrieve it from the original Magazine entity or Publisher entity.
How would be an optimized way of doing this?
Upvotes: 0
Views: 42
Reputation: 5857
One way to solve this would be using multiple JOIN tables, see Chapter 6.6 of Doctrine Association Mapping on Uni-Directional One-To-Many mapping.
The resulting annotations could look something like this (note that you should split your entities into several files, this is just for illustration of the ORM mapping annotations):
<?PHP
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="Magazine")
*/
class Magazine
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ManyToMany(targetEntity="Link")
* @JoinTable(name="Magazine_Links",
* joinColumns={
* @JoinColumn(name="Magazine_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @JoinColumn(
* name="Link_id", referencedColumnName="id", unique=true)}
* )
**/
protected $links;
public function __construct()
{
$this->links = new ArrayCollection();
}
}
/**
* @ORM\Entity
* @ORM\Table(name="Issue")
*/
class Issue
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ManyToMany(targetEntity="Link")
* @JoinTable(name="Issue_Links",
* joinColumns={
* @JoinColumn(name="Issue_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @JoinColumn(
* name="Link_id", referencedColumnName="id", unique=true)}
* )
**/
protected $links;
/**
* @ManyToOne(targetEntity="Magazine")
* @JoinColumn(name="magazine_id", referencedColumnName="id")
**/
protected $magazine;
public function __construct()
{
$this->links = new ArrayCollection();
}
}
/**
* @ORM\Entity
* @ORM\Table(name="Publisher")
*/
class Publisher
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ManyToMany(targetEntity="Link")
* @JoinTable(name="Publisher_Links",
* joinColumns={
* @JoinColumn(name="Publisher_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @JoinColumn(
* name="Link_id", referencedColumnName="id", unique=true)}
* )
**/
protected $links;
public function __construct()
{
$this->links = new ArrayCollection();
}
}
/**
* @ORM\Entity
* @ORM\Table(name="Link")
*/
class Link
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $uri;
}
?>
Upvotes: 1