Manejar Preferencias de Usuario desde un campo JSON en Laravel
Índice de contenido
En este apartado quiero mostrarte cómo implementé la parte de preferencias de usuario. Por el momento, podemos considerar dos preferencias:
- Modo oscuro (darkmode)
- Autoplay (autoplay)
La idea inicial podría ser agregar columnas en la tabla de usuarios para cada preferencia, pero esto no resulta escalable si más adelante se nos ocurren otras 10 preferencias, y tampoco me convence agregar demasiados campos a la entidad users. Otra opción sería crear una tabla relacional uno a uno, pero me parecía demasiado complicado para algo tan sencillo.
Por eso opté por una solución más sencilla usando JSON.
Recordemos que nos quedamos sobre como podemos usar el sistema de dominios y subdominios en Laravel.
Preferencias de usuario en base a JSON
Entonces lo primero que quiero mostrarte es que, desde Laravel que es donde tengo toda la información, imprimo la entidad de usuario en una constante:
<script>
window.Laravel = {!! json_encode([
'user' => Auth::user(),
]) !!}
</script>De esta forma, estoy compartiendo datos usuario, entre ellas un campo de usuario para manejar los datos extras como el de la preferencia de usuario y autoplay en formato JSON.
Entonces si realizamos aquí en la migración vas a ver qué campo es simplemente de tipo String:
$table->string('extra')->nullable()->default('');Lectura de preferencias en Vue
Para acceder a estas preferencias desde Vue, simplemente parseamos el JSON del objeto window.Laravel:
created() {
this.user = window.Laravel.user;
}El valor de cada preferencia se maneja como un toggle (verdadero o falso), por ejemplo true para activado y false para desactivado.
Actualización de preferencias en Laravel
Se crea un método global en Laravel para manejar todas las preferencias, llamado setExtra(). Este método:
- Obtiene el usuario autenticado (Auth::user() o auth('sanctum')->user()).
- Decodifica el campo extra en JSON, devolviendo un objeto vacío si no existe o está mal formado.
- Actualiza únicamente las preferencias enviadas en la solicitud.
function setExtra()
{
$user = Auth::user() ?? auth('sanctum')->user();
// si $user->extra tiene algun valor invalido, restablece a un objeto limpio
$extra = json_decode($user->extra ?? "{}") ?? json_decode("{}");
if (request("autoplay")) {
$extra->autoplay = request("autoplay") == 1 ? true : false;
}
if (request("darkmode")) {
$extra->darkmode = request("darkmode") == 1 ? true : false;
}
$user->update([
'extra' => json_encode($extra)
]);
}Lectura de preferencias en Vue (actualización dinámica)
Desde Vue, podemos leer y actualizar las preferencias de esta manera:
setExtraUser() {
try {
const extra = JSON.parse(window.Laravel.user.extra)
this.isDarkMode = extra.darkmode;
this.autoplay = extra.autoplay ? true : false;
if (!this.isDarkMode)
document.querySelector("html").classList.remove("dark");
} catch (error) {
// console.error(error)
}
},Si se activa una nueva preferencia, como darkmode o autoplay, se actualiza el objeto completo, conservando los valores anteriores. Esto permite extender las preferencias fácilmente, sin agregar nuevas columnas a la base de datos.
Ventajas de esta implementación
- Simplicidad: No hay que crear múltiples columnas en la tabla de usuarios.
- Escalabilidad: Podemos agregar nuevas preferencias sin modificar la base de datos.
- Seguridad: Siempre verificamos si la preferencia existe y hacemos un casteo seguro para evitar errores.
- Compatibilidad con Vue: Podemos actualizar y leer preferencias dinámicamente en la interfaz.
En resumen, esta estrategia de usar un campo JSON para las preferencias de usuario es más sencilla, flexible y extensible que crear múltiples columnas o relaciones adicionales en la base de datos.
El siguiente paso, es aprender como puedes usar Vue 3 con Laravel.
Acepto recibir anuncios de interes sobre este Blog.
Te voy a mostar un esquema para manejar preferencias de usuario como el autoplay, idioma o darkmode en Laravel mediante un campo.