Filtros con cláusulas condicionales, when en Laravel Livewire - Eloquent

Video thumbnail

Vamos a crear los filtros que implementamos antes mediante condicionales, pero ahora “modo Laravel”, que es el recomendado por el equipo de Laravel. La decisión final de cuál método emplear queda a criterio del lector.

Model::when(request('search'), function (Builder $query, string $search) ...

Uso básico de when()

Para esto, utilizaremos el método when().

  • El primer parámetro corresponde a la propiedad que se desea evaluar.
  • Si el valor está definido, se ejecuta el segundo parámetro, que es un closure:
Model::when(request('search'), function (Builder $query, string $search) {
    $query->where(function ($query) use ($search) {
       $query-><WHERES>
   })

En este closure:

  • $query permite aplicar cualquier operación con Eloquent.
  • $search es el parámetro evaluado que se suministra al closure.

Uso de condicionales

Anteriormente, te mostré cómo usar condicionales clásicos con Laravel. Este es un ejemplo de mi implementación favorita:

public function render()
   {
       // $posts = Post::paginate(15);
       // $posts = Post::where('id', '>=', 1);
       $posts = new Post();
       // $categories = Category::get();
       $categories = Category::pluck("title", "id");
      
       //filters
       if ($this->type) {
           $posts = $posts->where('type', $this->type);
       }
       if ($this->category_id) {
           $posts = $posts->where('category_id', $this->category_id);
       }
       if ($this->posted) {
           $posts = $posts->where('posted', $this->posted);
       }
       if ($this->search) {
           $posts = $posts->where(function($query){
               $query
               ->orWhere('id', 'like', '%'.$this->search.'%')
               ->orWhere('title', 'like', '%'.$this->search.'%')
               ->orWhere('description', 'like', '%'.$this->search.'%')
               ;
           });
       }
       if ($this->from && $this->to) {
           $posts = $posts->whereBetween('date', [date($this->from), date($this->to)]);
       }
       //filters
       $posts = $posts->paginate(15);
       return view('livewire.dashboard.post.index', compact('posts', 'categories'));
   }

Como puedes ver, es un enfoque funcional, pero ahora vamos a implementarlo usando when(), que es la forma oficial y recomendada por Laravel para aplicar condicionales.

$posts = Post::when($this->search, function (Builder $query, string $search) {
            $query->where(function ($query) use ($search) {
                $query->orWhere('id', 'like', "%" . $search . "%")
                    ->orWhere('title', 'like', "%" . $search . "%")
                    ->orWhere('description', 'like', "%" . $search . "%");
            });
        })

Implementación usando when()

Partimos directamente del modelo y aplicamos los filtros opcionales de manera clara:

$posts = Post::when($this->search, function (Builder $query, string $search) {
            $query->where(function ($query) use ($search) {
                $query->orWhere('id', 'like', "%" . $search . "%")
                    ->orWhere('title', 'like', "%" . $search . "%")
                    ->orWhere('description', 'like', "%" . $search . "%");
            });
        })
        ->when($this->type, function(Builder $query, $type) {
            $query->where('type', $type); 
        })
        ->when($this->category_id, function(Builder $query, $category_id) {
            $query->where('category_id', $category_id); 
        })
        ->when($this->posted, function(Builder $query, $posted) {
            $query->where('posted', $posted); 
        })
        ->when($this->type, function(Builder $query, $type) {
            $query->where('type', $type); 
        })
        ->when($this->to, function(Builder $query, $to) use($from) {
            $query->whereBetween('date', [date($from), date($this->to)]);
        })->with('category')
        ->orderBy($this->sortColumn, $this->sortDirection)
        ->paginate(15);

Cada filtro se aplica solo si existe el parámetro correspondiente.

El closure recibe los parámetros necesarios para aplicar las condiciones.

Filtros en la interfaz

La interfaz, la página web creada con blade y Laravel Livewire que acompaña estos filtros podría verse así:

<div class="grid grid-cols-2 gap-2 mb-3">
               <select class="block w-full" wire:model.live='posted'>
                   <option value="">{{ __('Posted') }}</option>
                   <option value="not">{{ __('Not') }}</option>
                   <option value="yes">{{ __('Yes') }}</option>
               </select>
               <select class="block w-full" wire:model.live='type'>
                   <option value="">{{ __('Type') }}</option>
                   <option value="advert">{{ __('Advert') }}</option>
                   <option value="post">{{ __('Post') }}</option>
                   <option value="course">{{ __('Course') }}</option>
                   <option value="movie">{{ __('Movie') }}</option>
               </select>
               <select class="block w-full" wire:model.live='category_id'>
                   <option value="">{{ __('Category') }}</option>
                   @foreach ($categories as $i => $c)
                       <option value="{{ $i }}">{{ $c }}</option>
                   @endforeach
               </select>
               <x-input wire:model.live='search' placeholder="{{ __('Search...') }}" />
               <div class="grid grid-cols-2 gap-2">
                   <x-input wire:model='from' placeholder="From" type='date' />
                   <x-input wire:model.live='to' placeholder="To" type='date' />
               </div>
           </div>

En definitiva, el uso del método when no es mas que una consulta que se ejecutar de manera opcional si se cumple una condición de verdadero o falso.

El método when() permite ejecutar consultas de manera opcional, solo si se cumple una condición.

Esto hace que el código sea más limpio, legible y totalmente compatible con la filosofía de Laravel.

https://github.com/libredesarrollo/book-course-laravel-livewire/blob/main/resources/views/livewire/dashboard/post/index.blade.php

Acepto recibir anuncios de interes sobre este Blog.

Vamos a aplicar los filtros definidos antes empleando los whens, que es la manera predefinida en Laravel.

| 👤 Andrés Cruz

🇺🇸 In english