How to map connection between three tables - symfony

I have three tables:
game columns: id | name (eg. 1 | Halo)
own columns: id | type_id | type_name (eg. 1 | 1 | on wishlist)
user columns: id | name (eg. 1 | Tomek)
Now what I have is a ManyToMany connection between those tables:
User (table user_own)
/**
* #ORM\ManyToMany(targetEntity="Own")
* #ORM\JoinTable(
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="type_id", referencedColumnName="id")}
* )
*/
Own (table own_game)
/**
* #ORM\ManyToMany(targetEntity="Game")
* #ORM\JoinTable(
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="game_id", referencedColumnName="id")}
* )
*/
My query:
public function getOwned() {
return $this->getEntityManager()
->createQuery('
SELECT u, o, g FROM AcmeGoBundle:User u
JOIN u.owners o
JOIN u.games g
')
->getResult();
}
I can retrieve games owned by particular user, but I can't connect type of ownership. How can I do this?

To crate ManyToMany with additional column with some data you need to create this by hand.
Doctrine ManyToMany relation crates a join table with id's of joined entities. So you need to create by your own Entity named ex. UserOwns with OneToMany relation to User and another OneToMany relation Own. Then you can add additional field with your data inside.
Check that question: Doctrine2: Best way to handle many-to-many with extra columns in reference table

Related

Symfony/Doctrine ManyToMany get records in order they assigned or saved

I have an entity called Item which has a ManyToMany connection with a JoinTable to an entity called Tags
This is working well. The problem is, that I need the tags in the exact order as they are chosen, not sorted by tag id, as I get them now when I call getTags() on the Item class. Is there a way to do that?
Use the join table to define that order.
Item_id | Tags_id | Order
--------+---------+------
1 | 1 | 2
1 | 2 | 1 <-- order for tags of item 1
1 | 3 | 3
-------+---------+------
2 | 42 | 1
2 | 1 | 2 <-- order for tags of item 2
-------+---------+------
3 | 3 | 1 <-- order for tags of item 3
... And the entities equivalent :
You are going from
//MToM : Many To Many
//OToM : One To Many
//MToO : Many To One
[Item] -MToM-> [Tags]
[Tags] -MToM-> [Item]
To
[Item] -OToM-> [ItemTags] -MToO-> [Tags]
[Tags] -OToM-> [ItemTags] -MToO-> [Item]
And, in your entities classes :
class Item
{
// some properties ...
/**
* #OneToMany(targetEntity="ItemTags", mappedBy="Item")
*/
private $ItemTags; //array
//more properties, and get/set
}
class Tags
{
// some properties ...
/**
* #OneToMany(targetEntity="ItemTags", mappedBy="Tags")
*/
private $ItemTags; //array
//more properties, and get/set
}
class ItemTags
{
/**
* #ManyToOne(targetEntity="Item", inversedBy="ItemTags")
* #JoinColumn(name="Item_id", referencedColumnName="id")
* ^-----^-------------------------^^---- Make sure to use the same than in your table !
*/
private $Item; // single Item
/**
* #ManyToOne(targetEntity="Tags", inversedBy="ItemTags")
* #JoinColumn(name="Tags_id", referencedColumnName="id")
* ^-----^-------------------------^^---- Make sure to use the same than in your table !
*/
private $Tags; // single Tags
private $Order;
// get/set and stuff
}

Symfony 4 doctrine many to many with findby -> Column not found: 1054

I'm trying to make a many to many join with a Doctrine findBy()
$articles = $entityManager->getRepository(Articles::class)
->findBy(['rubriquesrubriques'=>$id],['idarticles'=>"ASC"]);
But I get
An exception occurred while executing
'SELECT t0.idarticles AS idarticles_1,
t0.thetitle AS thetitle_2, t0.theslug AS theslug_3, t0.thedescription AS
thedescription_4, t0.thedate AS thedate_5, t0.users_idusers AS users_idusers_6
FROM articles t0 WHERE
articles_has_rubriques.rubriques_idrubriques = ?
ORDER BY t0.idarticles ASC' with params ["2"]:
SQLSTATE[42S22]: Column not found: 1054 Champ
'articles_has_rubriques.rubriques_idrubriques' inconnu dans where clause
The column articles_has_rubriques.rubriques_idrubriques exists in my DB,
but I don't see the INNER JOIN !
When I make my many to many with a simple Find():
$articles = $entityManager->getRepository(Articles::class)->find($id);
The query is correct!
SELECT t0.idrubriques AS idrubriques_1,
t0.thertitle AS thertitle_2
FROM
rubriques t0
INNER JOIN articles_has_rubriques ON t0.idrubriques =
articles_has_rubriques.rubriques_idrubriques
WHERE articles_has_rubriques.articles_idarticles = ?
is it impossible to perform my many2many query with a findBy in the 4.1.6 version of Symfony???
This is my ORM relation:
In entity Rubriques.php:
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Articles", mappedBy="rubriquesrubriques")
*/
private $articlesarticles;
In entity Articles.php
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Rubriques", inversedBy="articlesarticles")
* #ORM\JoinTable(name="articles_has_rubriques",
* joinColumns={
* #ORM\JoinColumn(name="articles_idarticles", referencedColumnName="idarticles")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="rubriques_idrubriques", referencedColumnName="idrubriques")
* }
* )
*/
private $rubriquesrubriques;
Thank you so much
My question was stupid :
I'have an easy way to do that:
$rubriqueActu = $entityManager->getRepository(Rubriques::class)->find($id);
$articles = $rubriqueActu->getArticlesarticles();
SQL:
SELECT t0.idarticles AS idarticles_1, t0.thetitle AS thetitle_2,
t0.theslug AS theslug_3, t0.thedescription AS thedescription_4,
t0.thedate AS thedate_5, t0.users_idusers AS users_idusers_6
FROM articles t0 INNER JOIN articles_has_rubriques
ON t0.idarticles = articles_has_rubriques.articles_idarticles
WHERE articles_has_rubriques.rubriques_idrubriques = ?

getReference() in Doctrine using other field than primary key

Is there any way to use the Symfony2's:
EntityManager::getReference($entityName, $id)
With some other field than a Primary Key?
Some code:
I have an entity:
class Category
{
/**
* #ORM\Id()
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id", type="integer")
*/
protected $id;
/**
* #ORM\Id()
* #ORM\Column(name="my_id", type="integer", nullable=false)
*/
protected $myId;
/**
* #ORM\ManyToMany(targetEntity="Category", inversedBy="child")
* #ORM\JoinTable(
* name="tcb_category_relations",
* joinColumns={#ORM\JoinColumn(name="category_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="parent_category_id", referencedColumnName="id")}
* )
*/
protected $parent;
/**
* #ORM\OneToMany(targetEntity="Category", mappedBy="parent")
*/
protected $child;
Which have a many to many relation to itself. This way, I make tree structures.
The thing is, $myId is much more important to and static - this id is not auto generated. So in case of import data, whoose can looks like this csv:
| my_id | my_id_parent |
| 1 | 0 |
| 4 | 1 |
| 5 | 1 |
| 7 | 5 | \ my_id could be unique!
| 7 | 4 | /
| 8 | 7 |
MyId is not unique, because any category can have multiple parents. So I can't use it as my primary key. I need to find reference for Category using the myId because while data import I need to flush entity manager every time after single category insert and every time run $em->find().
Of course I could use $em->getReference() but it's based on primary key and I don't know pk in data import.

Symfony2-Doctrine ManyToMany with 3 fields related

I'm having problems to define an association mapping and I don't know what to do to solve.
I want build a relation Many to Many between two objects but not only for one field.
One table refers to persons and the other to image, the target of this relation is represent when a person has been tagged by other person for this image
I need something like this:
| Tagged | Tagger | Photo |
| person_id_1 | person_id_2 | image_id_1 |
| person_id_3 | person_id_2 | image_id_1 |
| person_id_2 | person_id_4 | image_id_2 |
I try it using many to many relations like this:
/**
* #ORM\ManyToMany(targetEntity="Media")
* #ORM\JoinTable(name="persons_tagged",
* joinColumns={
* #ORM\JoinColumn(name="user_tagged", referencedColumnName="id"),
* #ORM\JoinColumn(name="user_tagger", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="media_id",referencedColumnName="id")
* }
* )
**/
private $employeeTagged;
When I try to update the schema by console, the table in DB it is created but without foreign keys because an exception of foreign key definition is threw and I have to create the foreign keys manually.
Someone has had a similar problem or a way to solve it? thanks
Create a new entity which has link to image, link to tagger (user), link to tagged (user).
You might also want to add created datetime, updated datetime, portion of image this person is in, description/text, etc.

ManyToManyToMany Symfony2

I've been trying to solved this issue about the Doctrine configuration I have set with three Entities in Symfony2 (v2.3.9)
Let's assume my application's goal is to manage the enrollment of certain people to different training courses. And I do want to split these courses in different groups: A, B and C.
So, my entities are:
Enrollment
Course
Group
The enrollment of a certain person can be to more than one course, but he/she cannot enroll to the same Course in different groups. That means, having some sort of table which looks like this one:
----------------------------------------
| enrollment_id | course_id | group_id |
----------------------------------------
| 1 | 1 | 1 |
----------------------------------------
| 1 | 2 | 3 |
----------------------------------------
So far, I've been able to create a ManyToMany relationship between the Enrollment entity and the Course entity.
Enrollment.php
...
/**
*
* #ORM\ManyToMany(targetEntity="Course", inversedBy="enrollments")
* #ORM\JoinTable(name="enrollment_course",
* joinColumns={#ORM\JoinColumn(name="enrollment_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="course_id", referencedColumnName="id")}
* )
*
*/
protected $courses;
.....
And the Course entity looks like this in terms of relationship:
Course.php
....
/**
*
* #ORM\ManyToMany(targetEntity="Enrollment", mappedBy="courses")
*/
protected $enrollments;
....
That makes the configuration incomplete.
-----------------------------
| enrollment_id | course_id |
-----------------------------
| 1 | 1 |
-----------------------------
| 1 | 2 |
-----------------------------
Considering the fact that, in order to complete the enrollment, I need both informations the Course and the Group. How can I translate this into Doctrine annotation?
Do you have any clue?
Thank you so much for your help.
Dani.
You need a make an entity for the sole purpose of joining the fields.
/**
* #ORM\Entity
* #ORM\Table(name="base",uniqueConstraints={#ORM\UniqueConstraint(name="enrollment_course_group_idx", columns={"enrollment_id", "course_id", "group_id"})})
*/
class Base
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Enrollment")
* #ORM\JoinColumn(name="enrollment_id", referencedColumnName="id")
**/
private $enrollment;
/**
* #ORM\ManyToOne(targetEntity="course")
* #ORM\JoinColumn(name="course_id", referencedColumnName="id")
**/
private $course;
/**
* #ORM\ManyToOne(targetEntity="Group")
* #ORM\JoinColumn(name="group_id", referencedColumnName="id")
**/
private $group;

Resources