I have been searching and searching and I cannot find an answer to this question. I need to make a query where I will have a dynamic number of OR
clauses. The documentation seems to suggest it is possible to pass an array of conditions to either where
or orWhere
, and yet when I try to do this, I end up with no results.
The query I need to make looks something like this:
SELECT * FROM tags WHERE name = $name1 OR name = $name2 ... OR name = $nameN;
I created an array of conditions and passed them to orWhere
like so:
// a user's tags for which all corresponding questions are queried
$user = User::with('tags')-where('id', Auth::user()->id)-get();
// an array of conditions formatted like the docs specify
$conditions = $user->tags->map(function ($item) {
return ['name', '=', $item->name];
})->all();
/*
outputs a plain array like this:
[
["name", "=", "php"],
["name", "=", "mysql"],
["name", "=", "laravel"],
]
*/
$tags = Tag::with([
'questions.answers',
'questions.user.answers',
'questions.tags'
])
->orWhere($conditions)
->get();
The result should be a collection of tags matching the user's tags, along with their related questions. But instead I get nothing. I have tried re-writing this query in a bunch of different ways and without eager loading related data as well, and nothing makes a difference. If I add a where
clause before the orWhere
clause, then the query returns only data filtered by the where
clause.
I'm at my wits' end with this. I have figured out a work-around, but it's complicated and really not ideal. I should be able to just use a simple orWhere
with an array of conditions rather than resorting to complicated hacks. Can anyone point out what I'm doing wrong and/or how I can achieve the results I'm trying to get? Thanks in advance.
CodePudding user response:
Have you tried something like this:
// For the first time, you need to use where statement
$tags = Tag::where(...);
// Then for the remaining conditions, you could use looping
// for chaining the orWhere statements
foreach ($queryStatements as $statement) {
$tags = $tags->orWhere(...);
}
// Then after all queries have been applied, call the get() method
$res = $tags->get();
This is how I would do it, hope this helps!
CodePudding user response:
Do you already try use the in
clause on where?
CodePudding user response:
If you put an array inside orWhere()
method.
Your query is gonna be like this:
`select * from `tags` where (`name` = ? and `name` = ? and `name` = ?) and `tags`.`deleted_at` is null`
As you can see the that it's search and
for every item you put in.
So here's how i solve the problem:
$query = Tag::with([
'questions.answers',
'questions.user.answers',
'questions.tags'
])->query();
//Foreach item in array
foreach ($datas as $data) {
$query->orWhere('name', '=', $data);
}
//Excute the query
$tags = $query->get();
Hope this solve your problem.
CodePudding user response:
If you just want to find tags by name you can use the whereIn()
method.
// Get array of current authenticated user's tags
$tags = auth()->user()->tags()->pluck('name');
/*
outputs an array like this:
['php', 'laravel', 'mysql']
*/
$tags = Tag::with([
'questions.answers',
'questions.user.answers',
'questions.tags'
])
->whereIn('name', $tags)
->get();
NOTE: The first argument for whereIn()
method is the column name you want to search in and the second argument is the array of values you are searching for.