Thanks for sharing an alternative of building that WHERE part of the query with Doctrine Criteria - we will cover them too but a bit further in this course: https://symfonycasts.com/screencast/doctrine-queries/criteria - also will show some use cases where they can be useful. IMO this definitely looks a bit more complex than the way shown in this video :)
Hi! I didn't know where to ask this so I'll do it in here because is about a search bar.
I already have a search bar for all of my data and it works fine, just like in this tutorial. The problem is when I want to search through specific data that each user has. I will show you what I've tried so far.
This the function I have in my Vehicle Repository:
public function createSearchResultsFromUser($slug = null, string $q = null): QueryBuilder
{
if ($slug && $q) {
$queryBuilder = $this->addOrderedByArrivedAtQueryBuilder()
->innerJoin('vehicle.publicEmployee', 'publicEmployee')
->addSelect('publicEmployee')
->andWhere('publicEmployee.owner = :slug')
->setParameter('slug', $slug)
->andWhere('vehicle.model LIKE :q OR publicEmployee.name LIKE :q OR publicEmployee.department LIKE :q')
->setParameter('q', '%' . $q . '%');
}
return $queryBuilder;
}
It seems to be that one of my problems(or may be the only one) is that I'm not passing the 'q' argument, because the error says that I have not defined the querybuilder, meaning that either $q or $slug is no present, but I have tried both and the $q is the one missing.
I'd really appreciate any help with this matter. BTW, I love your tutorials.
First of all, it seems that your code is fragile. The signature of the createSearchResultsFromUser() allow both args to be null, which means you will not hit that if ($slug && $q) in some cases. To make it work, you need to create a query builder first in that method, and only then add that if ($slug && $q) that will modify it, instead of creating. The correct code would be something like this:
public function createSearchResultsFromUser($slug = null, string $q = null): QueryBuilder
{
$queryBuilder = $this->addOrderedByArrivedAtQueryBuilder()
->innerJoin('vehicle.publicEmployee', 'publicEmployee')
->addSelect('publicEmployee');
if ($slug && $q) {
$queryBuilder
->andWhere('publicEmployee.owner = :slug')
->setParameter('slug', $slug)
->andWhere('vehicle.model LIKE :q OR publicEmployee.name LIKE :q OR publicEmployee.department LIKE :q')
->setParameter('q', '%' . $q . '%');
}
return $queryBuilder;
}
But I would suggest you to improve it even more and separate those search args in different if statements, like this:
public function createSearchResultsFromUser($slug = null, string $q = null): QueryBuilder
{
$queryBuilder = $this->addOrderedByArrivedAtQueryBuilder()
->innerJoin('vehicle.publicEmployee', 'publicEmployee')
->addSelect('publicEmployee');
if ($slug) {
$queryBuilder
->andWhere('publicEmployee.owner = :slug')
->setParameter('slug', $slug);
}
if ($q) {
$queryBuilder
->andWhere('vehicle.model LIKE :q OR publicEmployee.name LIKE :q OR publicEmployee.department LIKE :q')
->setParameter('q', '%' . $q . '%');
}
return $queryBuilder;
}
This way the slug and q will be independent, and you will add them only when they are not null.
Or just revisit your search business logic one more time.
Also, you have an error in the place where you call the method, you're passing those args as an array: $queryBuilder = $vehicleRepository->createSearchResultsFromUser([$slug, $request->query->get('q')]);
While it should be passed as 2 separate args: $queryBuilder = $vehicleRepository->createSearchResultsFromUser($slug, $request->query->get('q'));
I hope this helps! Sorry, but I can't help you more on it because it's a personal project question, we have bandwidth to answer tutorial questions only. Thank you for your understanding!
The most confusing for me is always using WHERE something IN () and second one is using UNION queries so I hope something will be in this course about it I end up using raw sql for these 2 scenarios
About UNION - we don't cover it in this tutorial, but with the knowledge you get in this course you should be able to leverage that MySQL function yourself as well
15 Comments
If anyone is slinging with PostgreSQL and wondering how to use the ILIKE operator, this code should help:
Hey @achabrzyk ,
Thank you for sharing this tip with our PostgreSQL friends :)
Cheers!
If someone wants as little 'raw' dql as possible, the where condition could also be written this way:
Hey S-H,
Thanks for sharing an alternative of building that WHERE part of the query with Doctrine Criteria - we will cover them too but a bit further in this course: https://symfonycasts.com/screencast/doctrine-queries/criteria - also will show some use cases where they can be useful. IMO this definitely looks a bit more complex than the way shown in this video :)
Cheers!
I wrote query by this example, but it does not generate or condition, no matter what.
turns out there was mistake in parantheses but I was not getting error, just wrong query.
Hey Darius,
Yeah, that happens, and it's the most complex bug to debug because you don't have an error. Glad to hear you figured it out, good job!
Cheers!
Hi! I didn't know where to ask this so I'll do it in here because is about a search bar.
I already have a search bar for all of my data and it works fine, just like in this tutorial. The problem is when I want to search through specific data that each user has. I will show you what I've tried so far.
This the function I have in my Vehicle Repository:
This is my controller:
and finally this is in my template:
It seems to be that one of my problems(or may be the only one) is that I'm not passing the 'q' argument, because the error says that I have not defined the querybuilder, meaning that either $q or $slug is no present, but I have tried both and the $q is the one missing.
I'd really appreciate any help with this matter. BTW, I love your tutorials.
Hey Octavio,
First of all, it seems that your code is fragile. The signature of the
createSearchResultsFromUser()allow both args to be null, which means you will not hit thatif ($slug && $q)in some cases. To make it work, you need to create a query builder first in that method, and only then add thatif ($slug && $q)that will modify it, instead of creating. The correct code would be something like this:But I would suggest you to improve it even more and separate those search args in different
ifstatements, like this:This way the slug and q will be independent, and you will add them only when they are not null.
Or just revisit your search business logic one more time.
Also, you have an error in the place where you call the method, you're passing those args as an array:
$queryBuilder = $vehicleRepository->createSearchResultsFromUser([$slug, $request->query->get('q')]);While it should be passed as 2 separate args:
$queryBuilder = $vehicleRepository->createSearchResultsFromUser($slug, $request->query->get('q'));I hope this helps! Sorry, but I can't help you more on it because it's a personal project question, we have bandwidth to answer tutorial questions only. Thank you for your understanding!
Cheers!
The most confusing for me is always using WHERE something IN () and second one is using UNION queries so I hope something will be in this course about it I end up using raw sql for these 2 scenarios
Hey Peter,
Yes we will cover WHERE IN() in this course, see: https://symfonycasts.com/screencast/doctrine-queries/where-in - that's a pretty simple thing, so it should not be a problem to understand that I think.
About UNION - we don't cover it in this tutorial, but with the knowledge you get in this course you should be able to leverage that MySQL function yourself as well
Cheers!
Do you know why my search is case sensitive? I worked around this by adding LOWER()
but wondering if it's just different version or another issue?
Hey
I think it's a PostgreSQL feature, and this workaround is pretty acceptable to use.
Cheers
Hello,
It depends on your query and your database server can you provide more information?
Cheers
"Houston: no signs of life"
Start the conversation!