Utiliza de forma correcta valores por default en Laravel Eloquent

Spread the love

algo que me gusta de Laravel es como simplifica algunas cosas. como la creación de un modelo:

User::create($request->validated());

Pero los requerimientos no siempre son tan simples.

Generalmente la creación de un modelo tiene condiciones adicionales,

por ejemplo, en nuestro caso puede ser que tenga que crear un usuario con un role especifico, que la cuenta se establezca como activa y que ademas sea necesario reiniciar la contraseña cada 30 días,

Así que al final terminamos con algo menos sencillo

$user = User::create([
            'name' => 'John Due',
            'email' => 'John.due@example.com',
            'password' => 'secret',
            'role' => 'basic',
            'is_enabled' => 1,
            'password_expired_at' => now()->addDays(30),
        ]);

Y en algunas ocasiones con algo mucho mas complicado.

Photo by Daniel Páscoa on Unsplash

Afortunadamente se puede solucionar de forma muy sencilla este problema; moviendo los valores por default a otra parte.

Valores por default en las migraciones

Este es el lugar mas conveniente para trasladar valores por default.

En nuestro ejemplo; role y is_enable se pueden pasar a la migración y usar el método default()

public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            //..
            $table->string('role')->default('basic');
            $table->boolean('is_enabled')->default(1);
            $table->dateTime('password_expired_at')->nullable();
            //..
        });

De esta forma ya no se requiere hacer referencia en el método create a los campos is_enabled y role.

$user = User::create([
            'name' => 'John Due',
            'email' => 'John.due@example.com',
            'password' => 'secret',
            'password_expired_at' => now()->addDays(30),
        ]);

Valores por default arreglo attributes

¿Qué pasa si cambia el default y ya lo establecí en la migración?

Bueno eso va a suceder tarde o temprano, pero no te preocupes.

Para eso Eloquent tiene la propiedad atrributes

Supongamos que ahora todos los usuario creados tendrán el role guest, para lograr esto solo agrega el campo role con su nuevo valor a arributes.

protected $attributes = [
        'role' => 'guest',
    ];

El arreglo atrributes tiene precedencia sobre el default en la base de datos, así que el cambio sera transparente y no tendrás que modificar nada en tu migración.

Toque final

Con los cambios anteriores se simplifico mucho la creación de nuestro usuario, pero no me siento conforme.

el campo password_expired_at en realidad no es un campo por default pero a mi no me gusta tener mas de una linea para el create si no es necesario.

Así que usare el evento creating de Eloquent, para asignar el campo password_expired_at

protected static function boot()
    {
        parent::boot();

        static::creating(function ($user) {
            $user->password_expired_at = now()->addDays(30);
        });
    }

Ahora cada vez que se crea un nuevo usuario se le asignara un tiempo valido de 30 días a su contraseña.

Y con esto, vuelve el orden de las cosas a su sitio.

$user = User::create($request->validated());

Conclusión

Laravel es muy flexible y en general tiene solución para muchos situaciones, como en este caso, que se puede establecer un valor por default mediante migraciones o mediante la propiedad attributes de Eloquent.

Esto nos ayuda a tener código mas simple de leer,

Cuando y como debes usar esto depende de tí. Pero en términos generales yo comienzo por las migraciones, luego la propiedad attributes y de ahí veo si puedo usar eventos u otra cosa para los otros parametros.

Para finalizar déjame tus comentarios y comparte este articulo!