Cómo implementar Global Scopes en Laravel

En un artículo anterior explicaba como usar los query scopes de forma local, ahora, en este nuevo artículo te voy a mostrar como crear query scopes globales.

En este artículo vamos a continuar con el ejemplo anterior:

1<?php
2namespace App\Models;
3 
4use Illuminate\Database\Eloquent\Model;
5 
6class User extends Model
7{
8 /**
9 * Scope a query to only include active users.
10 *
11 * @param \Illuminate\Database\Eloquent\Builder $query
12 * @return void
13 */
14 public function scopeActive($query)
15 {
16 $query->where('active', 1);
17 }
18}

Para crear nuestro global scope vamos a crear una clase llamada ActiveScope y la ubicaremos en app/Scopes la estructura de ese global scope sería la siguiente:

1<?php
2namespace App\Scopes;
3 
4use Illuminate\Database\Eloquent\Scope;
5use Illuminate\Database\Eloquent\Model;
6use Illuminate\Database\Eloquent\Builder;
7 
8class ActiveScope implements Scope
9{
10 public function apply(Builder $builder, Model $model)
11 {
12 $builder->where('active', 1);
13 }
14}

Y la forma de implementarlo en el modelo es la siguiente:

1<?php
2namespace App\Models;
3 
4use Illuminate\Database\Eloquent\Model;
5use App\Scopes\ActiveScope;
6 
7class User extends Model
8{
9 protected static function boot()
10 {
11 parent::boot();
12 static::addGlobalScope(new ActiveScope);
13 }
14}

En el articulo anterior comentaba que la forma de usar el scope sería esta:

1User::active()->get();

Pero ahora con la implementación del global scope ya no es necesario, solo con hacer:

1User::get();

es suficiente para obtener todos los registros que tengan el estatus activo.

Para remover un global scope en una consulta específica basta solamente con hacer lo siguiente:

1User::withoutGlobalScope('active')->get();

Desventaja del uso de los global scopes.

  • Complejidad adicional: Añadir global scopes puede hacer que tu código sea más complejo y difícil de entender y mantener.
  • Sobrecarga de memoria: Al utilizar global scopes, todas las consultas que se ejecuten para ese modelo incluirán automáticamente ese scope, lo que puede llevar a una sobrecarga de memoria en la aplicación.
  • Limitaciones en las consultas: Al utilizar global scopes, puede que no puedas realizar ciertas consultas o combinaciones de consultas que de otra manera serían posibles sin ellos.
  • Problemas de rendimiento: Dependiendo de la cantidad y complejidad de los global scopes que se hayan añadido, estos pueden ralentizar el rendimiento de la aplicación y hacer que las consultas se ejecuten más lentamente.
  • Dificultad para anular: A veces puede ser difícil anular un global scope en una consulta específica, lo que puede limitar la flexibilidad de tus consultas.

Es importante tener en cuenta que aunque los global scopes tienen estos inconvenientes, también pueden ser útiles en algunos casos específicos para hacer que tu código sea más fácil de mantener y aplicar restricciones de seguridad de forma global. Por lo tanto, es importante evaluar cuidadosamente si son adecuados para tus necesidades antes de implementarlos.

Para más información sobre la implementación de los query scopes visiten la documentacion: https://laravel.com/docs/9.x/eloquent#query-scopes

Angel Cruz's avatar
Autor
Angel Cruz