问题
In my case I have channels table that is in many to many relation with categories table.
I want to fetch the channels that their categories contain a dynamic value like doing LIKE
query on title of each category. but I need to check another columns of a channel by where clause.
This is a channel structure:
[
{
"id": 87,
"username": "ch1",
"title": "ch title",
"type": "channel",
"members": 210424,
"location": "tabriz",
"created_at": "2017-05-09 01:39:44",
"updated_at": "2017-05-16 17:19:28",
}
]
To get what I want I run this query:
$channels = Channel::orderBy('members', 'desc')
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->where([
['visible', 1],
['title', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->get();
Upper query return me all the channels like a query without whereHas
clause whiles when I use 'whereHas' alone, it return channels with in category that I want!
Am I use wrong syntax? Is it true to use where
and whereHas
clauses side by side?
UPDATE:
I need do like
query on channel's title or username, so I use orWhere
but the result is as before! it returns all channels to me! like query without whereHas
again.
So I use this query to do it,
$channels = Channel::orderBy('members', 'desc')
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->where([
['visible', 1],
['title', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->orWhere([
['visible', 1],
['username', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->get();
At first I thought the problem is orderBy clause as @exprator sayed, but after adding orWhere
I understood that orderBy
is not my issue.
回答1:
Channel::whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})->orderBy('members', 'desc')
use the whereHas before the order_by
->orWhere(function ($query) {
$query->where('visible', '=', 1)
->where('username', 'LIKE', '%' . $trend . '%')
->where('location', 'LIKE', '%' . $location . '%')
->where('members', '>', $members);
})
回答2:
Try to just use ->whereHas()
after the ->where()
. You don't need to duplicate anything normally.
$channels = Channel::where([
['visible', 1],
['title', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->orWhere([
['visible', 1],
['username', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->orderBy('members', 'desc')
->get();
回答3:
whereHas()
is wrongly used with where()
and orWhere()
. after whereHas
the second and third conditions have to be combined in a sub-routine. Currently your query will look like this:
SELECT * FROM foo WHERE something_where_has 1 AND WHERE something 2 OR WHERE something 3 ..
but I think what you wanted is your condition to look like this:
SELECT * FROM foo WHERE something_where_has 1 AND (WHERE something 2 OR WHERE something 3) ..
So this may serve you:
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->where(function($q) {
$q->where([
['visible', 1],
['title', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->orWhere([
['visible', 1],
['username', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]]);
})
回答4:
I solved this issue by duplicating whereHas
clause after orWhere
.
So to fetch the channels that are in categories that I want, I used this query:
$channels = Channel::orderBy('members', 'desc')
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->where([
['visible', 1],
['title', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->orWhere([
['visible', 1],
['username', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->get();
Maybe it's strange but worked nice!
来源:https://stackoverflow.com/questions/44582775/where-query-after-wherehas-not-work-as-it-should-in-laravel-5-4