Transpose a raw SQL query with doctrine - php

I'm pretty new to Doctrine ORM and I'm trying to transform a raw SQL query with doctrine to get an array of Entities.
Basically I want to get one of more course entities where a user is indirectly registered. The course id is in a traineeship table. The traineeship id and the user id are in a registration table.
Here's my SQL query :
SELECT * FROM course c
LEFT JOIN traineeship t
ON c.id = t.courseId
LEFT JOIN registration r
ON t.id = r.traineeshipId
WHERE r.userId = 2681;
Here's what I try to do with doctrine :
return $this->createQueryBuilder('c')
->andWhere('t.course = c')
->leftJoin('c.traineeships', 't')
->andWhere('r.traineeship = t')
->leftJoin('t.registrations', 'r')
->andWhere('r.id = :user')
->setParameter('user', $user)
->getQuery()
->execute();
With my raw SQL query, I get two expected results with a given id. With the generated query by doctrine, I get only one result. So I guess my doctrine use is bad.
(Doctrine relations :
Course OneToMany Traineeship
Traineeship OneToMany Registration
Registration ManyToOne User)

From the raw SQL I would expect the following query:
return $this->createQueryBuilder('c')
->leftJoin('c.traineeships', 't')
->leftJoin('t.registrations', 'r')
->andWhere('r.user = :user')
->setParameter('user', $user)
->getQuery()
->getResult();
Please note that I'm using ->andWhere('r.user = :user') instead of ->andWhere('r.id = :user') as I assume that registration.id holds the id of the registration but not the id of the user. In my query I furthermore assume that registration has an attribute user which holds a reference to the user.
The query should return an array of course entities.

Related

Symfony Doctrine if statement in querybuilder

Is it possible to insert IF statement inside doctrine query builder? For example: I have User and Group entities with OneToMany relationship. Group has boolean field hidden. How to create query builder which would select groups that are hidden = false if Group owner is not current user. So that only group owner can see hidden=true groups. and other users can only see hidden=false groups
$qb = $this->createQueryBuilder('group')
->where('group.owner = :userId')
->setParameter('userId', $user->getId())
->orderBy('group.created', 'DESC');
This should fit your needs
$qb = $this->createQueryBuilder('group');
$qb
->where(
$qb->expr()->andX(
$qb->expr()->eq('group.owner', ':userId'),
$qb->expr()->eq('group.hidden', true)
)
)
->orWhere($qb->expr()->eq('group.hidden', false))
->setParameter('userId', $user->getId())
->orderBy('group.created', 'DESC');
First part of query will keep a row only if current user is the owner and group is hidden.
Second part will include all non-hidden groups.

How to make a join query on Symfony with Doctrine?

I'm kinda stuck on using the querybuilder to create a join query.
There is a table called "Person" and a table called "Vacancy". If a person is linked to the vacancy the person.id and vacancy.id is saved in a table called "Candidacy". So how do I get all the persons who are linke to vacancy.id 1?
So where do I have to initiate the AppBundle:Candidacy entity?
$entity = $em
->getRepository('AppBundle:Person')
->createQueryBuilder('p')
->join('p.id', 'c')
->where('c.vacancyId= 1')
->getQuery()
->getResult();
Thank you in advance.
Example in your repository :
public function getPersonVacancy($personId) {
$qb = $this->createQueryBuilder('p');
$qb->leftJoin('p.vacancy', 'v');
$qb->select('v.name', 'v.id');
$qb->where('p.id = :personId');
$qb->setParameter('personId', $personId);
return $qb ->getQuery()->getResult();
This is to give you an example it may not work with copy paste.
Also, all join methods are explained in doctrine documentation, feel free to read it http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html
Looks like you have many-to-many relation.
You should link your Person and Vacancy table through Candidacy to Person and then Vacancy to Candidacy.
small example: Entity User is attached to Engagement via UserEngagement table.
$qb = $this->_em->createQueryBuilder()
->select('u')
->from($this->_entityName, 'u')
->join('u.userEngagements', 'ue')
->join('ue.engagement', 'en')
...

ManyToMany DQL from working SQL, accessing OneToMany

A working application uses a native SQL query to get items from a ManyToMany Entity relationship. Attempts to translate that query end up in a myriad of error messages. The Household entity has a ManyToMany relationship with Reason. Both entities & their relationships are properly defined. The joining table (household_reason) is not defined in .../Entity. The part that eludes me is how to join the Contact entity, with which the Household entity has a OneToMany relationship.
The working SQL:
select distinct r.reason
from reason r
join household_reason hr on hr.reason_id = r.id
join household h on h.id = hr.household_id
join contact c on c.household_id = h.id...
For starters, here's the beginning of a query builder in the Reason repository:
$query = $this->createQueryBuilder('r')->select('distinct r.reason')
->innerJoin('r.households', 'h')
Now that there's the plural households, how to I specify a relationship to a singular household?
Took a while, but the following works:
$query = $this->createQueryBuilder('r')->select('distinct r.reason')
->innerJoin('r.households', 'h')
->innerJoin('TruckeeProjectmanaBundle:Contact', 'c', 'WITH c.household = h.household')
->where('c.contactDate >= :startDate')
->andWhere('c.contactDate <= :endDate')
->andWhere('r.enabled = TRUE')
->orderBy('r.id')
->setParameters($dateCriteria)
->getQuery()
->getResult();

Implicit joins and Where in Doctrine - how?

I have a ManyToMany relation of Users and Roles. That is I have User table and entity class, Role table and entity and a joining table "user_role" width user_id and role_id columns.
Now, I recently tried to get users with their roles, by using joins, like this:
$qb = $this->createQueryBuilder('u')
->join('user_role', 'ur', Join::ON, "I didn't know what to put here, nothing worked ")
Anyway, thanks to this answer I added correct mapping (annotations) to my both entity classes and then removed my own join, letting Doctrine do the job:
$qb = $this->createQueryBuilder('u');
$q = $qb->getQuery();
$users = $q->getResult();
And this works. I have a list of all users, and then I can access their roles (thanks to User->getRoles() method).
However, now I want to list only users having certain roles, for example 'ROLE_ADMIN' and I have no idea how to do this:
$qb = $this->createQueryBuilder('u')
>where('what_to_put_here = :roles')
->setParameter('roles', 'what_to_put_here')
By the way, the SQL code generated by Doctrine looks like this:
SELECT u0_.id AS id_0, u0_.username AS username_1, u0_.personal_name AS personal_name_2, u0_.password AS password_3, u0_.email AS email_4, u0_.is_active AS is_active_5 FROM user u0_
So there is no JOIN. From the Doctrine docs I know this is called "lazy load" - the roles of certain user will be fetched on demand.
But then, how can I do something like this:
SELECT * FROM `user`
JOIN user_role on user_role.user_id = user.id
JOIN role on role.id = user_role.role_id
WHERE role.role_name = 'ROLE_ADMIN'
?
Use this:
$qb = $this->createQueryBuilder('u')
->innerJoin('u.roles', 'r')
->where('r.roleName = :roleNameParameter')
->setParameter('roleNameParameter', 'ROLE_ADMIN');
I'm assuming you mapped the column role_name as property roleName in the entity.

How to set a where clause filter with doctrine2 query buider in a many-to-many relation

I've been trying with no success to user doctrine2 query builder to fetch records in a related many-to-many table using a where clause.
I would like to reproduce the following statement:
SELECT [...] FROM Company
JOIN CompanyAddress ON CompanyAddress.CompanyId = Company.Id
JOIN Address ON Address.Id = CompanyAddress.AddressId
WHERE Address.State = ?
following some ideias found on google, stackoverfow and doctrine docs:
$qb = $this->_em->createQueryBuilder();
$qb->select('c')
->from('Company', 'c')
->where(':State MEMBER OF c.Address')
->setParameter('State', $arguments);
but the results are not the desired one. Any help? Thanks..

Categories