Doctrine2 Many To Many Polymorphic Relations - symfony

I try to create a Many To Many Polymorphic Relations with Doctrine2 in Symfony2.
I would like a single entity that is associate dynamically with multiples entities.
I want to get this following schema:
posts
id: integer,
name: string
======
videos
id - integer
name - string
======
tags
id - integer
name - string
======
taggables
tag_id - integer
taggable_id - integer
taggable_type - string
In taggables entity :
tag_id is the of the associate tag
taggable_id is the id of associate post
taggable_type is the type of associate entity ie 'Posts"
And I would like it to be the same with the "video" where:
tag_id represents the id of associate tag
taggable_id is the id of associate videos
taggable_type is the name of associate entity ie 'Videos'
and all this without duplicating table.
i'ved test multiple solutions but i never got this result :/
Thank you in advance for your help.

You could solve this with OOP, using inheritance.
Define an abstract class Taggable, and make Post and Video extend that class. Then create a OneToMany from Tag to Taggable.
Doctrine will take care of everithing, supposed that you choose between Single Table Inheritance or Class Table Inheritance.
I would choose Class Table, though.
More on this subject here.

Related

Doctrine ORM : Joined table inheritance

Related to this previous topic : Database : Account table with Joined Tables Inheritance
I've created a joined tables inheritance in my database (MySQL) :
client_id attributes are both PK and FK.
Now I need to represent it with Doctrine ORM but I can't find a solution of how to make that.
I created, with Symfony commands, the Client entity and for the ClientCompany entity I don't know which relationship to use nor how to use the Client ID as primary key of the CompanyClient entity.
Does anyone know how to do it?
First of all, be really carefull with inheritance, this is a really good feature of doctrine but need to be used with a lot of cautious because of it's counterpart.
For your case, i would advise to not try to put "person" and "company" under the same abstract "client" class for conception reason i already explain in this answer since a company and a person are totally different things: Symfony 6 inheritance Mapping : How to submit a form depends on a clicked radio button?
But i will still answer on how to properly do a join table inheritance :
AbstractClient.php
#[Entity]
#[InheritanceType('JOIN_TABLE')]
#[DiscriminatorColumn(name: 'discr', type: 'string')]
#[DiscriminatorMap(['person' => Person::class, 'company' => Company::class])]
abstract class Client
{
// you do not need clientType since it is hold by the "discr" column
// And if you want to know what type your client is you can do it using
// if($client instanceof Person::class) { do something}
}
Person.php
#[Entity]
class Person extends Client
{
// ...
}
Company.php
#[Entity]
class Company extends Client
{
// ...
}
Take a look at #[InheritanceType('JOIN_TABLE')]
It will create one table for each entity and they will share ids.
If you create a company with id 2, there will be a client with id 2. So a Person with id 2 will never be possible.
But if you use 'SINGLE_TABLE' it will create only one table with all the field of all the entity which will be empty depending on which child you inserted inside.
But again i strongly advise you to not use join table inheritance for your usecase

Grakn, create entity composed by entity?

I'm very new on GRAKN.AI and I'm wondering if in a GRAKN's graph I can create an "entity" composed by an "enitity". I know I can do the following code:
table sub entity
has book;
book sub resources datatype string;
But can I relate the "book" as an entity to the "table" ??
I need to have "book" as a complex concept and not as a simple resource.
Thanks,
Davide.
An alternative solution is to go through a relationship which allows you to define things more explicitly. For example,
To define a relationship you start by defining roles which provide context for how things relate to each other. For example:
insert
thing-on-top-of-table sub role;
table-with-thing-on-top sub role;
You then say how these roles link to the relationship and to the entities:
insert
sits-on sub relation
relates thing-on-top-of-table
relates table-with-thing-on-top;
table plays table-with-thing-on-top;
book plays thing-on-top-of-table;
The above is pretty much the schema of your simple knowledge base.
Now we can add some data. Let's say some book is on top of some table:
insert
$book isa book;
$table isa table;
(thing-on-top-of-table: $book, table-with-thing-on-top: $table) isa sits-on
Naturally you can expand things from here. For example you can give your book a title via a resource.
Side Note: Resources Vs Entities
The basic rule of thumb for relating something as a resource or as another entity depends on how much information you want to express in the model as well as if something can be defined by a data literal (e.g. String, Int, Long, etc . . . ).
For example a book is an entity because it is made up of multiple resources which help identify the book. I.e. the title, isbn, etc. . . those resources on the other hand are simple data values. A title is nothing but a string so there is no reason to make the title an entity, that should be fine as just a resource.
You couold model two entites bookand table and have a relation that you could call something like belongs and add the roles you need e.g. book-role and table-role
If the concepts are hierarchically related you can use inheritance.
table sub entity
has some property
book sub table
has additional property
Inheritance is usefull for classification you can easily understand that two sub entities are related and both can be retrieved by querying the parent.
match $t isa table;
would return the books as they are children entities of table.

symfony create a table with attribute from multiple entities

I have different entities like:
Element, Status, Action, Contributor ...
And I need to create an entity, let say Synonym, which can be related to one of these previous entities
My entity Synonym, can be a synonym of the entity Element or Status or Action ...
I try to use a MappedSuperclass but I'm really lost.
I think this kind of relation is common and must be easy to create with doctrine but I can't find the good way.

Comment entity related to Article or Product

I have entities "Article" and "Product". Now I want to add comments to these 2 entities. Should I create 2 different entities "ArticleComment" and "ProductComment" with the same properties, and build a ManyToOne relation to their respective entity, or create a single "Comment" entity and find a way to build a relation to both "Article" and "Product" entities. Considering solution #2, how could I do that ?
Considering solution #2, how could I do that ?
One way would be to use Single Table Inheritance
Single Table Inheritance is an inheritance mapping strategy where all classes of a hierarchy are mapped to a single database table. In order to distinguish which row represents which type in the hierarchy a so-called discriminator column is used.
This means that you can easily create two separate entities ArticleComment and ProductComment both extending Comment. Then you use the advantages DiscriminatorMap column provides.
Your Comment entity could hold a relation called parent for instance that would refer to either your Article or Product entities. By creating new instance of ArticleComment or ProductComment your discriminator map field would be automatically populated depending on which type you're using.
This would also give you advantages with using DQL to query related comments by their type. Example from documentation:
$query = $em->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee');
And more. You can read that chapter here. Of course this is just a sample and you can use completely different approach.

Can't get any entity associated to a tree entity

I'm working on an e-learning application and I have to categorize courses. So my Section entity is one of Tree extension. In order to retrieve all courses of a section, I made the following assoication:
/**
* #ORM\OneToMany(targetEntity="Svi\FormationBundle\Entity\Course", mappedBy="section")
*/
private $courses;
The problem is that when I try get courses in twig doing this {% if section.courses|length > 0 %}, I receive this error message
Key "courses" for array with keys "id, titre, sommaire, slug, deactivated, lft, lvl, rgt, root, __children" does not exist in SviFormationBundle:Formation:see_courses.html.twig at line 22.
I made a dump on the section object and it displayed all attributes except ones of OneToMany and ManyToOne associations. Any help please? Isn't it possible to associate other entities to a Tree entity? If so how to make a nested classification in Symfony? Thanks.
In your query, you have to explicitely add the 'join' or 'leftJoin' to the 'Course' entity.

Resources