Manejar Preferencias de Usuario desde un campo JSON en Laravel

Por aquí quería mostrarte un poco como implemente la parte del las preferencias de usuario así las puedo llamar Que de momento sería uno se lo puede ocurrir bueno la primera preferencia por ejemplo sería el modo oscuro pero más adelante se me ocurrió otra que es para el autoplay.
La referencia más directa sería crear aquí en la tabla de usuarios una columna para el Dark Mode otra columna para el autoplay y así hasta que se te ocurran 10 preferencias más cosa que a mí no me termina de convencer ya que obviamente oye estar agregando campos y campos y campos sobre la entidad de usuarios que ya tiene muchos para cosas tan sencillas no me parece pudieras agregar una tabla relacional es decir una relación de uno a uno pero me parece más complicado todavía en el sentido de que para algo tan sencillo como una preferencia estar manejando esas estructuras y luego estar trayendo esa información desde el arabel si existe si no existe y toda la cuestión yo quería algo más sencillo qué fue lo que se me ocurrió te lo muestro a continuación.

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('');

Entonces ya aclarado un poco sobre lo que es el campo y cóm lo estoy imprimiendo por acá para tener esas referencias en Vue vamos a ver cómo lo gestiono es muy sencillo realmente aquí lo primero que hago es leer esas preferencias del objeto windows ya que la final ese objeto que te mostraba esta es una variable que se construye aquí windows laravel y esa la puedo leer perfectamente desde Vue tal cual puedes ver ya que es un json simplemente la parseo y por aquí referenci sus valores tal cual puedes ver entonces esa viene siendo la primera estrategia:

created() {
    this.user = window.Laravel.user;
}

Fíjate que estoy pasando uno si es true y menos un si es falso puedes intentar con true o false a veces el cero no llega Entonces yo prefería hacerlo de esta forma para siempre recibir esos datos Lo importante es que es de tipo toggle verdadero o falso entonces puedo jugar con cualquier valor que yo considere en este caso los mencionados y por aquí tengo un método Global en Laravel que me permite definir todas estas preferencias que yo llamé como estra entonces aquí obviamente obtenemos el usuario autenticado ya sea mediante las cookies o la sesión luego de esto lo que hacemos Es un casteo aquí es interesante ya que es lo que te comentaba recordemos que esta función si le pasas cualquier cosa te va a devolver una sección el espera recibir es un objeto por lo tanto si esto es nulo o simplemente un String vacío daría una sección y es por eso que aquí hago una verificación antes de casteo si esto es nulo o simplemente vacío devolvería un objeto vacío entonces para qué funcionaría esta esto se debe a que si por cualquier razón Esto está mal formado entonces devuelva simplemente un objeto vacío otra vez si esto es distinto de vacío o de nulo:

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)
    ]);
}

Es importante ir verificando si esto lo está pasando por lo mencionado antes porque este método es global por lo tanto cualquier otra preferencia lo voy a manejar siempre desde acá y las preferencias se envían de manera individual aquí otra vez Fíjate que solamente estoy enviando la del Dark mode y no la da autoplay por lo tanto, solo actualiza el condicional de darkmode.

Si revisamos lo que tenemos en la base de datos no es más que un json, por ejemplo voy a colocar lo del autoplay voy a recargar aquí otra vez aquí Fíjate que está el autoplay en falso pero no está nada del Dark Mode:

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)
 }
},

Lo voy a colocar por ejemplo en true aquí ya aparecería en true y ahora voy con el Dark Mode y si revisamos aquí también está y se anexa al dato que teníamos antes Entonces esto es gracias a la verificación que te indicaba por acá otra vez si esto es lo que le estamos pasando simplemente tocamos esto y estamos trabajando desde objeto original que lo estamos obteniendo del usuario y actualizamos todo el objeto y de esta forma me parece mucho más sencilla mucho más agradable mucho más entendible que estar creando un montón de columnas adicionales para manejar las preferencias de usuario y la podemos extender muy fácilmente.

A la final como moraleja siempre tenemos que ir verificando si está definida si no está definida si está definida la obtenemos si no está definida simplemente dejamos un valor por defecto y estar siempre pendiente los casteos para que no de una sección y simplemente deja de ejecutar el resto de la aplicación y también que aparezca aquí un feo mensaje de error así que ahora sí ya con eso acabamos

- Andrés Cruz

In english

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz En Udemy

Acepto recibir anuncios de interes sobre este Blog.

!Cursos desde!

10$

En Udemy

Quedan 2d 19:20!


Udemy

!Cursos desde!

4$

En Academia

Ver los cursos

!Libros desde!

1$

Ver los libros
¡Hazte afiliado en Gumroad!