Reputation: 1931
I'm trying to find the best way to design relations between entities from my model.
Imagine the following Doctrine 2 entities:
class ImageHistory
{
/**
* @var Image
*/
protected $current;
/**
* @var \Doctrine\Common\Collections\Collection
*/
protected $old;
}
class Dog
{
protected $name;
/**
* @var ImageHistory
*/
protected $imageHistory;
}
class Cat
{
protected $name;
/**
* @var ImageHistory
*/
protected $imageHistory;
}
I would like to establish two one-to-many bidirectional Doctrine relations where Cat
and Dog
are the owning sides of the relations. Both Cat
and Dog
classes have this entity configuration:
manyToOne:
imageHistory:
targetEntity: ImageHistory
joinColumn:
name: image_history_id
referencedColumnName: id
How to represent the other side of te relation ?
oneToMany:
owner:
targetEntity: <What can I write here?>
mappedBy: imageHistory
I imagine a solution where Cat
and Dog
inherite an Animal
entity class, so I can move the ManyToOne relation into the Animal
class and put Animal
as targetEntity of the OneToMany relation. But the problem reappears if I have a new SoundHistory
entity and: Cat
, Dog
and new Car
and Boat
classes must have a relation to it.
A can't just add SoundHistory
as oneToMany relation to the Animal
class because Car
and Boat
won't inherite from it. So I still can't fill the targetEntity
of my OneToMany relation in the ImageHistory
entity.
What is the best way to design the entity model in this case?
Upvotes: 19
Views: 361
Reputation: 42
The best way to do what you need is use a separate join table to represent the relations between Cat
, Dog
and ImageHistory
, SoundHistory
. For this you can use one to many unidirectional mapping with join table. Doctrine docs found here, thanks to NaeiKinDus: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html#one-to-many-unidirectional-with-join-table
The point is - image & sound histories are stored independently and the join table cat_image_history
stores which Cat
owns which ImageHistory
. So Doctrine will get your cat's id
, check the cat_image_history
and get the correct ImageHistory
by image_history_id
. Same way you can add SoundHistory
only for dogs or for both cats and dogs.
The mapping can look something like this:
Cat:
type: entity
manyToMany:
imageHistory:
targetEntity: ImageHistory
joinTable:
name: cat_image_history
joinColumns:
cat_id:
referencedColumnName: id
inverseJoinColumns:
image_history_id:
referencedColumnName: id
unique: true
Upvotes: 0
Reputation: 684
A Many-To-One Relation is unidirectional, so you can't represent the other side.
Also, you should consider creating a super entity, if you really want to store the Dogs and Cats in the same table.
Upvotes: 0