The has()
method is very handy in a many-to-many relationship when used to find the model instances where the relationship exists.
In some cases, though (for example: "users who have _not_ an assigned role") a hasNot()
method returning the results where the relationship _doesn't_ exist would be useful.
$users = User::hasNot("role")->get();
Good idea. It can just be an alias for something that's already possible: User::has('role', '<', 1)
As noted above, its currently possbile by using the < 1 operator.
A hasNot method would be much better.
:+1:
hasNot would definitely look better!
+1 for this
I agree, having this would increase code readability.
+1
@taylorotwell (as far as I can understand) It doesn't have the same functionality to full extend. I needed something like this;
$users = User::hasNot("role", function($q) {
$q->where('name', 'moderator');
})->get();
I'd like to get users with no moderator
role attached (as an example). I cannot find a simple and proper way for it.
:+1:
@furkanmustafa In the laravel API docs http://laravel.com/api , the whereHas function is documented to also support the operater and count argument.
Builder|Builder whereHas(string $relation, Closure $callback, string $operator = '>=', int $count = 1)
$users = User::whereHas("role", function($q) {
$q->where('name', 'moderator');
}, '<', 1)->get();
@ricksuggs ah! ok. even if it doesn't read as I hoped, that's still a complete solution. thanks.
As a side note, if it ever does get implemented solely for readability, wouldn't this be more readable (doesNotHave vs hasNot):
$users = User::doesNotHave("role")->get();
@ricksuggs If we have doesNotHave
we need to have doesHave
instead of has
. So hasNot
is better IMO.
I create a PR.
+1 For hasNot
@gowthamSelvaraj Already added https://github.com/laravel/framework/pull/6686.
How about an orDoesntHave function?
+1 for hasNot()
+1 for hasNot() too
Working on a solution to filter users by role right now.
I'll work with the solution given above, but I've "instinctively" tried "hasNot" before.
+1 for hasNot()
This is inside the framework for one year now...
https://github.com/laravel/framework/blob/5.2/src/Illuminate/Database/Eloquent/Builder.php#L836
Exactly, but not with the OR statement.
+1 for hasNot()
i cant see this in laravel 5.3 Builder Class? has this been removed?
@shez1983
I think it now called whereDoesntHave()
https://github.com/laravel/framework/blob/5.3/src/Illuminate/Database/Eloquent/Builder.php#L910
@Alexwijn
Exactly, but not with the OR statement.
Thats true, but you can always reverse the order:
$query->whereHas('something')->orWhereDoesntHave('something_else')
//fails
=> will not work since method orWhereDoesntHave does not exist
But you can refactor this into:
$query->whereDoesntHave('something_else')->orWhereHas('something')
//works
+1 hasNot()
+1 hasNot()
+1 hasNot()
+1 hasNot()
doesntHave
already exists people?
But like I said a long time go, it does not exist with the OR statement.
According to the source we can pass OR
as a second parameter:
$query->doesntHave('relationName', 'OR');
Most helpful comment
doesntHave
already exists people?