Doctrine2 - Polymorphic Associations to Same Entity from Two Different Entities - php

I am still trying to understand polymorphic associations in Doctrine2.
As I understand it, basic polymorphic associations work by using inheritance. If, for example, I had tables/classes OWNER, CAT and DOG, then the way to enable $owner->pet to point at either the CAT or the DOG table, would be to have them each extend a fourth class, PET, which is known as a mapped superclass. Then $owner->pet could return either a CAT or a DOG depending on what had been assigned, and Doctrine2 would be able to distinguish them.
That's simple enough. But what if I want to have two polymorphic associations which can point at the same object? For example, lets say that I have a table of ADMIRALS, each of which could command a FLEET or a PLANET. Let's also say that I have a table of SECTORS, each of which could contain a PLANET or a MOON.
Let's assume that I want $admiral->command to reference both PLANETS and FLEETS, and that I want $sector->contents to reference both PLANETS and MOONS. PLANET can't extend both command and contents as mapped superclasses. Is there a different way to make this work?

you can try ResolveTargetEntityListener see
you can point admiral's command property to an Interface, which is implemented by both PLANETS
and FLEETS
the same is with sector's contents

Related

CakePHP relationship scenario

I'm trying to figure out the appropriate relationship setup/schema for the following scenario and I suppose I'm a bit unclear as to the relationships themselves.
My models: Accident and People.
An accident may involve many people. A person may be related to many accidents.
For example: An accident happens to Abe and Bob. Abe may be the related to multiple accidents.
I have an accidents table, a people table and an accidents_people table with the appropriate schema. I want the user to be able to add an accident independently of a person, and a person independently of an accident, and then when they edit an accident, link it to multiple people. Is this possible?
$people = $this->Accident->Person->find('list'); //should give me list of all people
$this->set('people', $people); //should allow me to access a list of all people in view
TLDR:
What you're describing is the "Has and Belongs To Many" relationship (also known as HABTM):
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasandbelongstomany-habtm
Note / Another option:
Another option is the HasMany Through, which is basically HABTM, but with a model specifically for the join table. This allows a bit more flexibility if you need more than just the 3 fields in your join table (id, person_id, and accident_id)
Model convention:
If you're following the CakePHP Model and Database Conventions, your "People" model should really be "Person".
It's "okay" to use non-standard, but if you're learning Cake, you're better off trying to stick to them for now.
(looking at your code, which correctly uses "Person" as the model, I assume you just typed it wrong in your description)

Many-To-One with multiple target entities

This seems simple but I can't get it right:
There are three entities: Fruit, Vegetable and Snack. Snack has the fields id, time and food. Food is a reference to either one fruit or one vegetable. So it is basically a many-to-one/one-to-many relationship as one snack will always only hold one food. But there is more than one target entity.
How would I map this in Doctrine2?
A simple solution I would have used before knowing Doctrine2 would be to use two fields: food_type and food_id. But how can I make a connection from food type to the correct entity? I thought about an array of JoinColumns but can't find a way to connect the correct entity. I also had a look at mapped superclasses because there is a DiscriminatorColumn, but it also seems to be the wrong approach. If I get it right the superclass can't be an entity itself - so I cannot create a food entity.
Any help is appreciated. I'm sure I am missing something simple here.
You can create a (abstract) mapped superclass called Food, which can hold some basic information for Fruit and Vegetable.
The keyword for your question is inheritance mapping, this is the documentation for it: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/inheritance-mapping.html#inheritance-mapping
Then you could reference this mapped superclass in your entity relationship.

Class Table Inheritance without shared autoincrement ID in Doctrine 2?

Is it possible to have a CTI in Doctrine 2 that does not shared the autoincrement? For example, i have a Pet entity and two sub-classes, Cat and Dog. However, if i create two dogs and one cat, the next ID for BOTH entities will be 4. I wanted Dog and Cat to have it's own autoincrement.
I don't see how would this work, regardless of doctrine.
What if you don't know which entity to expect and have only the id?
For example get the Pet with id 4?
You can't query by base class, which IMHO breaks the purpose of inheritance.
With CTI you get separate tables, but still it is just plain inheritance, CTI is just a object-relational mapping shema.
From the object model perspective having two entities of same type with the same id just doesn't make sense.
So you can either stick with what you have, or get rid of the inheritance completely and manage Cat and Dog as two independent entities. I would suggest you stick with the first option.
Also, with CTI there is no autoincrement on Cat and Dog, only on Pet. Child tables just copy the ID from parent, regardless how the ID was generated.

Yii Framework - Two instances of the same relation

I have a model Animal in Yii which has two relations, mainRace and secondaryRace, both of them being an instance of the Race model.
How can this be translated into the relations array of Animal model aswell as in the Race model?
Looks like you'd need a many to many relationship, so you'll need one more table (animal_race).
See the Yii Relational page for more info on how to setup a MANY_MANY
Edit: if you're wanting to limit the animal to only two races, then you'd probably want to have a main_race_id / secondary_race_id in the Animal model (assuming an animal can only ever be in two races, what if the animal is entered in multiple events?).
And then you'd use a BELONGS_TO setup. That way you can easily find all the animals for a given race using a HAS_MANY relationship.

Doctrine2: Should parent classes in single table inheritance be abstract?

I'm writing constructors for my classes in a Doctrine2 application, let's say Fruits, Apple, Bananas.
Fruits is the parent class, where Apples and Bananas inherit from Fruits using single table inheritance on field type.
On the Doctrine2 documentation page, there is an example provided for single table inheritance. If we are always discriminating using Single Table Inheritance, should the base class Fruits be abstract because the discriminator field must always be set? If so, should the constructor for Fruits also be protected to prevent this behavior?
As there are no methods in your parent class "Fruits" that you need to redeclare I don't think there is an explicit need for it to be declared as abstract.
Also you may find a use case where you may want an instance of "Fruit" to be persisted (undetermined as to what type of fruit it is). Marking the parent as abstract will prevent you from being able to do this.
Maybe fruit is a bad example. But the Person example they have in the documentation is better. Employees will inherit Person definitions. But I may also want to persist just an instance of Person, undetermined of type. Hence the "person" = "Person" in the #DiscriminatorMap.
http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/inheritance-mapping.html#single-table-inheritance

Categories