banner-date-mutators-con-eloquent

Como ya hemos visto anteriormente es mucho más fácil trabajar con fechas y horas cuando lo hacemos con Carbon, el componente que extiende el DateTime de PHP y conocimos en Manipular fechas con el componente Carbon en Laravel 5. Sin embargo, cuando creamos nuevos atributos de tipo datetime para una entidad en particular, de buenas a primera, no podemos usar la variedad de métodos que nos ofrece el componente para este tipo de atributo, pues estos son devueltos como un string que trabajaríamos con la clase DateTime de PHP y no como un objeto Carbon. Veamos en este tutorial cómo podemos corregir este pequeño problema.

Supongamos que queremos trabajar con una entidad llamada Event que tendrá como atributos el nombre del evento: name y sus fecha de inicio y fin: started_at , y finished_at . Para generar dicho modelo junto con su respectiva migración hacemos:

php artisan make:model Event -m

Con esto obtenemos como resultado el archivo de migración /database/migrations/create_events_table.php para crear la tabla en la base de datos, en cual incluimos lo siguiente:

public function up()
    {
        Schema::create('events', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->datetime('started_at');
            $table->datetime('finished_at');
            $table->timestamps();
        });
    }

Luego, ejecutamos la migración con php artisan migrate , no sin antes comprobar que tenemos configurado el archivo .env con las credenciales de una base de datos.

Ahora crearemos el controlador para trabajar con nuestro modelo:

php artisan make:controller EventsController

Además, creamos una ruta de tipo resource en /app/Http/routes.php  de esta manera:

Route::resource('event', 'EventsController');

y creamos una vista para agregar nuevos eventos usando el componente Styde\Html para crear los campos del formulario:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">       
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
        <title>Styde</title>
    </head>
    <body>
        <div class="container">
            <div class="row">
                <div class="panel panel-default">
                    <div class="panel-heading">New event</div>
                    <div class="panel-body">

                        {!! Form::open(['route' => 'event.store', 'method' => 'POST']) !!}
                            {!! Field::text('name', ['class' => 'form-control']) !!}
                            {!! Field::input('date', 'started_at', null, ['class' => 'form-control']) !!}
                            {!! Field::input('date', 'finished_at', null, ['class' => 'form-control']) !!}
                       
                            <button type="submit" class="btn btn-default">Create</button>
                        {!! Form::close() !!}
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

Ejecutando por consola php artisan serve  e ir a la URL http://localhost:8000/event/create obtenemos:

event-create-view

Ahora, para convertir los atributos de tipo datetime a instancias de Carbon, vamos al archivo /app/Event.php  y añadimos el array $dates  de la siguiente manera:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Event extends Model
{
    protected $dates = [
        'started_at', 
        'finished_at'
    ];
}

En el array $dates  deberían estar todos aquellos atributos de tipo datetime que queremos manipular con los métodos helper proporcionados por Carbon.  Por defecto, Eloquent en Illuminate\Database\Eloquent\Model , establece a los atributos created_at y updated_at como instancias de Carbon y por medio del array $dates  nos permite que nuestros campos también lo sean; y de esta manera podemos trabajar con esos atributos y los métodos helpers de Carbon, como por ejemplo en el método store de EventController podemos hacer algo como:

public function store(Request $request)
    {
        $event = new Event;
        $event->name = $request->name;
        $event->started_at = $request->started_at;
        $event->finished_at = $event->started_at->addMonth();
        
        return $event;
    }

donde no tomamos el valor para la fecha de fin del formulario sino que automáticamente le asignamos un mes a la fecha de inicio (campo anterior), obteniendo:

{"name":"Evento de inicio","started_at":"2015-12-16 00:00:00","finished_at":"2016-01-16 00:00:00"}

¡Bien! con esto ya tenemos a disposición todas posibilidades que nos ofrece los métodos de Carbon para estos atributos, espero que les sea de utilidad para sus proyectos de Laravel. No dejes de comentar en caso de duda y compartir en las redes sociales.

Material relacionado

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

Lección anterior Cargando Service Providers condicionalmente en Laravel 5.1 Lección siguiente Encriptar datos en Laravel