I don't know the exact term for showing the entity in second level of array.
I have entity Doctor. see my list in my image
If you can see the entity Person under the Doctor list. It display the Person entity like firstName and lastName. How can I show the same in facilityPackageDoctors? I expect it shows the package name and the facility, and what it displays now is not the list of facilityPackageDoctors. Here is my query
public function getFacilityPackageDoctors($facilityId){
$query = $this->createQueryBuilder('d')
->leftJoin('d.facilityPackageDoctors', 'fpd')
->leftJoin('fpd.facilityPackage', 'fp')
->where('fp.facility = :parameter')
->setParameter('parameter', $facilityId)
->getQuery();
return $query->getResult();
}
Do I have something to setup on this? sorry for the term I used.
thanks to ccKep. I found the solution by adding addSelect()
public function getFacilityPackageDoctors($facilityId){
$query = $this->createQueryBuilder('d')
->leftJoin('d.facilityPackageDoctors', 'fpd')
->leftJoin('fpd.facilityPackage', 'fp')
->addSelect('fpd')
->where('fp.facility = :facilityId')
->setParameter('facilityId', $facilityId)
->getQuery();
return $query->getResult();
}
Try with something like that
public function getFacilityPackageDoctors($facilityId){
$query = $this->createQueryBuilder('d')
->leftJoin('d.facilityPackageDoctors', 'fpd')
->leftJoin('fpd.facilityPackage', 'fp')
->addSelect('fp as facility')
->where('fp.facility = :parameter')
->setParameter('parameter', $facilityId)
->getQuery();
return $query->getResult();
}
Related
Good afternoon, please tell me how to get the column data:
{#ORM\Index(name="localities_names_idx", columns={"name_ru", "name_cn", "name_en"})
I tried using queryBuilder :
$qb
->select('a')
->from(Locality::class, 'a')
->where('a.name_ru = :name_ru')
->andWhere('a.area is null')
->setParameter('name', 'Moscow');
$query = $qb->getQuery();
Without success
I need it for:
$em = $this->entityManager;
$qb = $em->createQueryBuilder();
$qb
->select('a')
->from(Locality::class, 'a')
->where('a.name_ru = :name_ru')
->andWhere('a.area is null')
->setParameter('name', 'Москва');
$query = $qb->getQuery();
$result = $query->getResult(Query::HYDRATE_SCALAR);
$location = new Location();
$location->setLocality($result[0]['a_id']);
$location->setAddress($address);
$em->persist($location);
$em->flush();
return $location->getId();
Edit: This turned into a review, but might as well keep it here
You're using index wrong.
I'm guessing you're using it incorrectly. I'm assuming you want an index for faster search. However, the way you do now you've created a combined index. Example:
{#ORM\Index(name="thing_colour_idx", columns={"thing", "colour"})
Thing | Colour
--------------
Car Blue
Car Red
Bike Green
Bike Yellow
If you always (or at least most of the time) select by both columns, eg you always search for a BLUE+CAR, or a GREEN+BIKE, than this is the way to go.
However, if you to select all Thing=Car, without colour, then this index does nothing. You want this:
indexes={
#ORM\Index(name="thing_idx", columns={"thing"}),
#ORM\Index(name="colour_idx", columns={"colour"})
}
You're not using getResult as intended
You do ->getResult(Query::HYDRATE_SCALAR), but then follow it up with a ->setLocality($result[0]['a_id']). Unless you have performace issues, you dont work with IDs, thats a problem for Doctrine, not you. You should only care about objects:
$locality = $em
->createQueryBuilder()
->from(Locality::class, 'a')
->where('a.name_ru = :name_ru')
->andWhere('a.area is null')
->setParameter('name', 'Москва') // <- btw, this should be 'name_ru', same as two lines heigher
->getQuery()
->getSingleResult();
$location = new Location();
$location->setLocality($locality);
Dont use the querybuilder like that, use a repository
You're now placing service logic and query logic in one code. That is incorrect. An example of the way Symfony is intented:
class LocalityRepository extends ServiceEntityRepository{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Locality::class);
}
public function getLocalityByRuName(string $name): Locality
{
return $this->createQueryBuilder('a')
->where('a.name_ru = :name_ru')
->andWhere('a.area is null')
->setParameter('name_ru', $name);
->getQuery();
->getSingleResult();
}
}
class YourService
{
public function __construct(
private LocalityRepository $localityRepository
){}
public function somethingSomething()
{
$locality = $this->localityRepository->getLocalityByRuName('Москва');
$location = new Location();
$location->setLocality($locality);
}
}
Final note: Try not to use a ->flush() in a service. The job of a service is to do work, not to decide what to do it. A controller decides when something is done. Suppose you have another service which in which you alter things, but DONT want to flush them. You can now no longer use any service method that flushes.
The error was that there were no name properties Ru
I have in a repository this code:
public function getNotAssignedBy($speciality, $diploma)
{
$qb = $this->createQueryBuilder('j')
->select('DISTINCT(j.id) id', 'j.firstName', 'j.lastName', 'j.dateBirth', 'j.sex')
->leftJoin('j.qualifications', 'q')
;
if ($speciality) {
$qb->andWhere('q.speciality = :speciality_id')->setParameter('speciality_id', $speciality);
}
if ($diploma) {
$qb->andWhere('q.diploma = :diploma_id')->setParameter('diploma_id', $diploma);
}
$result = $qb->getQuery()->getResult();
return $result;
}
How can I get only rows where id not exists in another entity ??
Any help. Thanks
You can achieve it with something like this:
....
// construct a subselect joined with an entity that have a relation with the first table as example user
$sub = $this->createQueryBuilder();
$sub->select("t");
$sub->from("AnotherEntity","t");
$sub->andWhere('t.user = j.id');
// Your query builder:
$qb->andWhere($qb->expr()->not($qb->expr()->exists($sub->getDQL())));
Hope this help
Since I can't comment, so I will post a fixed version of #Matteo's solution
The correct way to use createQueryBuilder in this case is by using EntityManager. See my comment in the code below.
$sub = $this->_em->createQueryBuilder(); // _em stands for entity manager here. While $qb may use repositories createQueryBuilder() which requires alias
$sub->select("t");
$sub->from("AnotherEntity","t");
$sub->andWhere('t.user = j.id');
// Your query builder:
$qb->andWhere($qb->expr()->not($qb->expr()->exists($sub->getDQL())));
So recently I have been thinking and can't find a solution yet to this problem since my lack of development with doctrine2 and symfony query builder.
I have 2 tables:
Goals: id,user_id,target_value...
Savings: id,goal_id,amount
And I need to make a select from goals (all the informations in my table are from the goals table, except that I need to make a SUM(amount) from the savings table on each goal, so I can show the user how much did he saved for his goal)
This is the MySQL query:
select
admin_goals.created,
admin_goals.description,
admin_goals.goal_date,
admin_goals.value,
admin_goals.budget_categ,
sum(admin_savings.value)
from admin_goals
inner join admin_savings on admin_savings.goal_id=admin_goals.id
where admin_goals.user_id=1
group by admin_goals.id
It returns what I want but I have no idea how to implement it with doctrine or query builder, can you please show me an example in both ways?
I highly appreciate it !
I am going to assume you need this fields only and not your AdminGoals entity. On your AdminGoalsRepository you can do something like this:
public function getGoalsByUser(User $user)
{
$qb = $this->createQueryBuilder('goal');
$qb->select('SUM(savings.value) AS savings_value')
->addSelect('goal.created')
->addSelect('goal.description')
->addSelect('goal.goalDate')
->addSelect('goal.value')
->addSelect('goal.budgetCat') //is this an entity? it will be just an ID
->join('goal.adminSavings', 'savings', Join::WITH))
->where($qb->expr()->eq('goal.user', ':user'))
->groupBy('goal.id')
->setParameter('user', $user);
return $qb->getQuery()->getScalarResult();
}
Keep in mind that the return object will be an array of rows, each row is an associated array with keys like the mappings above.
Edit
After updating the question, I am going to change my suggested function but going to leave the above example if other people would like to see the difference.
First things first, since this is a unidirectional ManyToOne between AdminSavings and AdminGoals, the custom query should be in AdminSavingsRepository (not like above). Also, since you want an aggregated field this will "break" some of your data fetching. Try to stay as much OOP when you are not just rendering templates.
public function getSavingsByUser(User $user)
{
$qb = $this->createQueryBuilder('savings');
//now we can use the expr() function
$qb->select('SUM(savings.value) AS savings_value')
->addSelect('goal.created')
->addSelect('goal.description')
->addSelect('goal.goalDate')
->addSelect('goal.value')
->addSelect('goal.budgetCat') //this will be just an ID
->join('savings.goal', 'goal', Join::WITH))
->where($qb->expr()->eq('goal.user', ':user'))
->groupBy('goal.id')
->setParameter('user', $user);
return $qb->getQuery()->getScalarResult();
}
Bonus
public function FooAction($args)
{
$em = $this->getDoctrine()->getManager();
$user = $this->getUser();
//check if user is User etc depends on your config
...
$savings = $em->getRepository('AcmeBundle:AdminSavings')->getSavingsByUser($user);
foreach($savings as $row) {
$savings = $row['savings_value'];
$goalId = $row['id'];
$goalCreated = $row['created'];
[...]
}
[...]
}
If you use createQuery(), then you can do something like this:
$dqlStr = <<<"DSQL"
select
admin_goals.created,
admin_goals.description,
admin_goals.goal_date,
admin_goals.value,
admin_goals.budget_categ,
sum(admin_savings.value)
from admin_goals
inner join admin_savings on admin_savings.goal_id=admin_goals.id
where admin_goals.user_id=1
group by admin_goals.id
DSQL;
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery($dqlStr);
$query->getResult();
On the other hand, if you would like to use createQueryBuilder(), you can check this link: http://inchoo.net/dev-talk/symfony2-dbal-querybuilder/
I have an entity that has a column "inventoryLcoation_id" that has a many to one relationship. For some reason when I use createQueryBuilder() it is not returning that value in my ajax call, but it returns everything else: id, name, etc etc.. This is not an issue with Symfony2, its an issue with my lack of knowledge :)
Here is my query builder code:
$qb = $this
->createQueryBuilder('p')
->select('p.id', 'p.name')
->where('p.inventoryLocation = :inventoryId')
->andWhere('p.account = :account_id')
->setParameter('inventoryId', $value)
->setParameter('account_id', $account_id)
->orderBy('p.id', 'DESC');
if($qb->getQuery()->getArrayResult()){
return $qb->getQuery()->getArrayResult();
}else{
return false;
}
What do I need to code to have it also include the value from the inventoryLocation table which is mapped to the column value "inventoryLocation_id"?
Thanks so much for your help in enlightening my understanding to the awesome world of Symfony2!
try a join:
$qb->join('p.inventoryLocation','i')
and in the select especify both entities
$qb->select('p','i')
it should look like this:
$qb = $this
->createQueryBuilder('p')
->select('p','i')
->join('p.inventoryLocation','i')
->where('p.inventoryLocation = :inventoryId') // or ->where('i = :inventoryId')
->andWhere('p.account = :account_id')
->setParameter('inventoryId', $value)
->setParameter('account_id', $account_id)
->orderBy('p.id', 'DESC');
I have 3 tables: user, user_followers and blog_posts.
Users can follow other users and users are related to blog_post by user_id.
I need to get all blog posts that people I follow have written.
I tried something like:
$followedUsers = $user->getFollowedByMe(); //This one works
$posts = $entityManager->getRepository('<BundleHere>:BlogPosts')
->findBy(array('user_id' => $followedUsers));
And I tried a lot more variations but can't figure it out. Maybe someone knows a better way to search by multiple objects not just one.
You can use this kind of code in your BlogRepository.php in example.
public function getBlogPost($userId)
{
return $this
->_em
->createQueryBuilder('p')
->leftJoin('p.user', 'u')
->where('u.id = :id')
->setParameter('id', $userId)
->getQuery()
->getResult();
}
createQueryBuilder('p') will automatically create the select and from (select entity (post ?) from table).
Then, you can use it like this :
$posts = $entityManager->getRepository('<BundleHere>:BlogPosts')->getBlogPost($userId);
I can't give you the exact query because we don't have enough informations about your entities. But this way, you can write nice queries to get exactly what you want.
You can do:
$posts = $entityManager->getRepository('<BundleHere>:BlogPosts')
->createQueryBuilder('b')
->whereIn('b.user', $followedUsers)
->getQuery()
->getResult();
'user' should be the name of property used to hold the user in the Blogpost object.
So i figured it out (thanx guys for pointing me in the right direction with queryBuilder).
$followedByMe = $user->getFollowedByMe(); //Getting users i follow
$followedIds = $followedByMe
->map(function( $obj ) { //Using map method to create an array of id's for all followers
return $obj->getId(); //Value to put into array (in this case id)
})->toArray(); //Create an array and assign it to $followedIds variable
$qb = $em->getRepository('<BundleHere>:BlogPosts')->createQueryBuilder('b');
$posts = $qb->where($qb->expr()->in('b.user', $followedIds ))
->orWhere('b.user = :my_id')->setParameter('my_id', $user->getId()) //Get my posts too
->getQuery()
->getResult();