Mass assingnment en Eloquent

Vimos en la anterior entrega que podemos crear un nuevo registro haciendo esto:

use App\Noticia;
$noticia = new Noticia;
$noticia->titulo = 'Mi primera noticia';
$noticia->cuerpo = 'Estoy realmente emocionado';
$noticia->save();

Imagina que esta tabla tuviese un montón de campos. Necesitaríamos una línea por cada campo.

Si tenemos en cuenta que normalmente los datos suelen venir de un formulario ¿no habría una forma de automatizar este trabajo? ¿No se supone que Laravel es tan fantástico?

Pues sí, existe una forma de ahorrarnos trabajo. Vamos a verla paso a paso.

Vamos a suponer que tenemos una matriz con los datos que nos han llegado de un formulario. Por ejemplo:

$datosFormulario = [
	'titulo' => 'Mi primera noticia',
	'cuerpo' => 'Estoy realmente emocionado'
];

NOTA: En Laravel podemos recoger los datos de un formulario con un objeto Request, pero ya lo veremos más adelante.

Con lo que sabemos hasta ahora haríamos algo como ésto:

$datosFormulario = [ 'titulo' => 'Mi primera noticia', 'cuerpo' => 'Estoy realmente emocionado' ];

use App\Noticia;
$noticia = new Noticia;
$noticia->titulo = $datosformulario['titulo'];
$noticia->cuerpo = $datosFormulario['cuerpo'];
$noticia->save();

Vamos, que tenemos otra vez una línea por cada campo. Aquí solo hay dos campos, pero si tenemos muchos más el código cada vez va siendo más largo y más feo (y somos muy vagos para teclear tanto ¿verdad?).

$datosFormulario = [ 'titulo' => 'Mi primera noticia', 'cuerpo' => 'Estoy realmente emocionado' ];

use App\Noticia;
$noticia = Noticia::create($datosFormulario);

Pero ¡no tan rápido vaquero! Vamos a ejecutar ese código en Tinker y ver qué pasa. Cuando intentemos crear el registro vamos a ver un error como éste:

Illuminate\Database\Eloquent\MassAssignmentException with message 'titulo'

¿A qué se debe esto? ¿Por qué tiene que ser todo tan complicado?

Pues en este caso debes dar las gracias porque Laravel te está protegiendo de listillos que pueden querer buscar agujeros en tu aplicación.

Ten en cuenta que cuando recibes datos de un formulario siempre existe la posibilidad de que estén manipulados y busquen un agujero en tu aplicación.

Ten en cuenta que hay herramientas que pueden simular el envío de datos de un formulario y se pueden añadir otros campos.

Por ejemplo, imagina que en tu aplicación tienes un campo admin que sirve para controlar si un usuario tiene privilegios de administrador.

Un usuario malintencionado podría añadir este campo admin al formulario y al crear el nuevo registro tendrías un usuario con permisos que no debería.

Para evitar estos problemas Eloquent protege todos los campos. Si queremos que a algún campo se le pueda asignar un valor de esta manera debemos indicarlo de manera explícita.

Esto se hace editando el modelo, en este caso Noticia.php y añadimos la propiedad $fillable:

protected $fillable = [ 'titulo', 'cuerpo' ];

Con lo que el modelo noticia quedaría:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Noticia extends Model
{
    protected $fillable = [ 'titulo', 'cuerpo' ];
}

Ahora sí, los campos titulo y cuerpo pueden recibir datos de un array:

use App\Noticia;
$noticia = Noticia::create($datosFormulario);

NOTA: Sal de Tinker y vuelve a entrar para evitar problemas.

Sin embargo el campo id sigue estando protegido. Si el array con los datos hubiese sido:

$datosFormulario = [
	'id' => 1,
	'titulo' => 'Mi primera noticia',
	'cuerpo' => 'Estoy realmente emocionado'
];

Verías que esto no está permitido.

Recuerda, a no ser que lo indiques en el modelo los campos están protegidos contra la asignación masiva.

Autor:
Nivel: Principiante
Palabras clave:
Fecha publicado:
Fecha actualizado: 21-08-2016

Otros capítulos de la misma serie

Este capítulo es parte de la serie: Eloquent.

Y muchos más en preparación.

Disponible en los planes: Laravel hero