A veces creo que complicamos el código innecesariamente cuando estamos desarrollando un sistema.

Te pongo un ejemplo sencillo: tienes un sistema con 3 tipos de usuario: cliente, editor y administrador, pero necesitas una forma de evitar que los clientes accedan al panel de administración, y que sólo los administradores puedan acceder a los módulo de configuración. ¿Cómo resolverías este problema?

La mayoría de los desarrolladores al oír sobre grupos o tipos de usuario, inmediatamente piensan en crear una tabla «groups» y relacionarla con la tabla «users», o quizás piensan que hace falta instalar un componente externo para lidiar con el problema de «administración de grupos». Sentry, por ejemplo, crea una tabla «groups» y, como se trata de un componente para uso general, te da la posibilidad de asignar más de un grupo a cada usuario, es decir, vas a requerir de una tabla intermedia «group_user».

Tu base de datos quedará entonces con las siguientes tablas:

  • users
  • groups
  • group_user (un grupo contiene varios usuarios, un usuario puede estar en más de un grupo)

Por otro lado el código para crear un grupo con Sentry es así:

Sentry::createGroup(array(
    'name' => 'Subscribers',
    'permissions' => array(
        'admin' => 1,
        'users' => 1,
    ),
));

y luego podemos encontrar un grupo por ID o por nombre, por ejemplo:

try {
    $group = Sentry::findGroupByName('admin');
} catch (Cartalyst\Sentry\Groups\GroupNotFoundException $e) {
    echo 'Group was not found.';
}

Una vez que obtenemos el grupo podemos asignarlo al usuario de esta forma:

$user->addGroup($group);

Pero si quisiéramos bajar el nivel de un usuario de administrador a editor, quizás tendríamos que asegurarnos de quitar el nivel administrador antes de agregar el grupo editor?

$user->removeGroup($Sentry::findGroupByName('admin'));
$user->addGroup(Sentry::findGroupByName('editor'));

Realmente no estoy del todo seguro, quizás debería leer un poco más la documentación de Sentry o escribir/ejecutar pruebas… Pero ¿Realmente hace falta todo esto?

Keep it simple

En la descripción mencionaba que un usuario puede ser de 3 tipos (user, editor, admin) pero no necesita pertenecer a 2 o 3 tipos a la vez, sólo a uno (por ende no necesitaremos la tabla «group_user»), y estos tipos serán fijos en el sistema, no requieren ser dinámicos (por ende tampoco necesitamos la tabla «groups»). ¿Podríamos usar simplemente un campo de tipo enum dentro de la tabla users?

ALTER TABLE `users` ADD `role` ENUM( ‘user’, ‘editor’, ‘admin’ ) NOT NULL AFTER `id` ;

O en Laravel:

$table->enum(‘role’, [‘user’, ‘editor’, ‘admin’])

Luego asignar un usuario a un grupo es tan sencillo como esto:

$user->role = ‘editor’;

Comprobar si un usuario pertenece a un grupo sería tan fácil como escribir:

if ($user->role === ‘editor’)

Si no quieres usar una columna enum o tu cliente piensa agregar otros niveles de acceso más adelante, puedes crear una tabla roles y agregar una columna «role_id» en la tabla «users». Esto sigue siendo una solución más sencilla que agregar la tabla extra «role_user» o «group_user», que deberías agregar sí y sólo sí, un usuario puede tener más de un role o pertenecer a más de un grupo.

Mal uso del patrón repositorio

Lo mismo sucede con el patrón repositorio. Eloquent ofrece una manera muy sencilla de acceder a datos:

User::all()

Sin embargo he visto a muchos desarrolladores hacer cosas como ésta:

<?php

namespace App\Repositories;

user App\Models\User;

class UserRepository {

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function getAll()
    {
        return $this->user->all();
    }
}

Why?

Los repositorios tienen casos de uso interesantes, sobretodo para encapsular consultas complejas de Eloquent, como he explicado antes, pero tal como ocurre en el ejemplo de users y groups, úsalos sólo si los necesitas, no te compliques de manera innecesaria.

Conclusión

Frameworks como Laravel nos brindan la posibilidad de tener una API sencilla con la cual desarrollar nuestros proyectos, tratemos de crear nosotros soluciones simples también, adaptadas a las necesidades de nuestro proyecto y utilizando arquitecturas o soluciones más avanzadas sólo cuando realmente hagan falta.


¡Hey! ¿Sabías que sólo por pocas horas tenemos un descuento de 40% en nuestro plan anual?

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.