En el post de hoy vamos a trabajar con Laravel, PHP y consultas SQL con WHERE. Como bien sabes, en MySQL o motores similares podemos agrupar condiciones usando paréntesis, estableciendo así un orden.
Por ejemplo, si queremos encerrar 2 condiciones y luego evaluarlas con un AND, haríamos algo así:
select * from `productos` where `id_establecimiento` = ? and (`descripcion` LIKE ? or `codigo_barras` LIKE ?) order by `descripcion` asc;
En este caso hacemos un and
entre la primera comparación y el resultado de la segunda que está encerrada entre paréntesis para evaluar un or
.
Esto es importante porque (para este ejemplo) si no se usaran paréntesis se podrían ver los productos de todos los establecimientos si es que el código de barras coincide.
Entonces veamos cómo agrupar y evaluar condiciones booleanas de la base de datos entre paréntesis usando el Query Builder y ORM de Laravel.
Entonces veamos un ejemplo con un builder. Para agregar un WHERE hacemos lo siguiente:
<?php
$builder = Producto::orderBy("descripcion")->where("id_establecimiento", "=", Auth::user()->establecimiento->id);
En este caso usamos el método where
del modelo de Laravel. La primera vez se agregará como un where normal sin operadores, pues es la única condición.
Si seguimos agregando más condiciones where entonces se colocará un and
automáticamente.
Por otro lado, si queremos agregar un where pero que sea con OR, invocamos al método orWhere
.
Podemos encerrar las condiciones entre paréntesis. Para ello podemos usar where
o también orWhere
, pero le pasamos una función como primer argumento.
Esa función recibirá un argumento en el cual podremos seguir usando los métodos del builder, pero todo lo que hagamos dentro de ella va a quedar entre paréntesis. Por ejemplo:
<?php
if ($busqueda) {
$builder->where(function ($query) use ($busqueda) {
$query->where("descripcion", "LIKE", "%$busqueda%")->orWhere("codigo_barras", "LIKE", "%$busqueda%");
});
}
En este caso invoco a where
con una función, y dentro de ella hago un where
pero además un orWhere
. Esas 2 condiciones se van a quedar encerradas entre paréntesis y evaluarse con las condiciones externas si es que existen.
Para depurar voy a devolver la consulta SQL generada por Laravel, así podrás ver la diferencia clara para agrupar las condiciones WHERE
.
Veamos un primer ejemplo sin paréntesis. El builder queda así:
<?php
$builder = Producto::orderBy("descripcion")->where("id_establecimiento", "=", Auth::user()->establecimiento->id);
if ($busqueda) {
$builder->where("descripcion", "LIKE", "%$busqueda%")->orWhere("codigo_barras", "LIKE", "%$busqueda%");
}
Generando la siguiente consulta que tiene un error de lógica ya que las últimas 2 condiciones deberían agruparse:
select * from `productos` where `id_establecimiento` = ? and `descripcion` LIKE ? or `codigo_barras` LIKE ? order by `descripcion` asc
Y ahora veamos cómo queda si agrupamos las condiciones. El código queda así:
<?php
$builder = Producto::orderBy("descripcion")->where("id_establecimiento", "=", Auth::user()->establecimiento->id);
if ($busqueda) {
$builder->where(function ($query) use ($busqueda) {
$query->where("descripcion", "LIKE", "%$busqueda%")->orWhere("codigo_barras", "LIKE", "%$busqueda%");
});
}
Con la siguiente salida en la consulta, demostrando que las condiciones dentro de la función quedan entre paréntesis y se evalúan primero.
select * from `productos` where `id_establecimiento` = ? and (`descripcion` LIKE ? or `codigo_barras` LIKE ?) order by `descripcion` asc
Con todo lo que te mostré no quiero decir que sea malo no agrupar consultas o cosas similares, solo te enseñé cómo encerrar condiciones entre paréntesis si usas Laravel para interactuar con la base de datos SQL.
Para terminar te dejo con más tutoriales de Laravel en mi blog.
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Ayer estaba editando unos archivos que son servidos con el servidor Apache y al visitarlos…
Esta web usa cookies.