Skip to content

Conversation

zakariaarrid
Copy link

Introduction of whenWhere function to Laravel Query Builder

Usage Examples

$users = User::query()
            ->whenWhere($request->active, 'is_active', true)
            ->whenWhere($request->role, 'role', $request->role)
            ->get();

instead of

 $users = User::query()
            ->when($request->active, function($query) {
                $query->where('is_active', true);
            })
            ->when($request->role, function($query, $role) {
                $query->where('role', $role);
            })
            ->get();

@zakariaarrid zakariaarrid marked this pull request as draft October 25, 2024 14:33
@rodrigopedra
Copy link
Contributor

IMO, this is already short enough:

$users = User::query()
    ->when($request->active, fn ($q) => $q->where('is_active', true))
    ->when($request->role, fn ($q, $role) => $q->where('role', $role))
    ->get();

And also, IMO, more expressive/declarative of intent of its parameters.

Other than that, what about whenWhereNull, whenWhereNotNull, whenWhereIn, whenWhereNotIn, whenWhereHas, whenWhereExists, whenWhereRaw, whenWhereNot, etc.?

@gdebrauwer
Copy link
Contributor

@rodrigopedra you can even make your example shorter by using the higher-order 'when' method 😄

$users = User::query()
    ->when($request->active)->where('is_active', true)
    ->when($request->role)->where('role', $role)
    ->get();

@howdu
Copy link

howdu commented Nov 7, 2024

It'd be useful if when auto handled the where clause wrapping for use with OR conditions.

$users = User::query()
    ->when(
        $search,
        fn (Builder $query) => $query->where(
            fn (Builder $query) => $query
                ->where('test', $search)
                ->orWhereNull('test')
        )
    )

@sydgren
Copy link

sydgren commented Dec 20, 2024

It'd be useful if when auto handled the where clause wrapping for use with OR conditions.

$users = User::query()
    ->when(
        $search,
        fn (Builder $query) => $query->where(
            fn (Builder $query) => $query
                ->where('test', $search)
                ->orWhereNull('test')
        )
    )

You mean exactly like the current behavior?

$search = 'search';

User::query()
    ->when($search, fn (Builder $query) => $query->where('test', $search)->orWhereNull('test'))
    ->ddRawSql();

// SQL: select * from `users` where (`test` = 'search' or `test` is null) and `users`.`deleted_at` is null

User::query()
    ->when($search)->orWhere([['test', $search], ['test', null]])
    ->ddRawSql();

// SQL: select * from `users` where ((`test` = 'search' or `test` is null)) and `users`.`deleted_at` is null

Both work like you want, last one even double wraps it for extra protection! 🛡️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants