Hoy vengo a mostrar un truco o atajo al programar en Laravel, se trata de guardar un modelo con los campos que tiene el formulario de manera automática, en lugar de especificar cada propiedad manualmente.
Es decir, a partir de los campos que tiene el formulario guardar el modelo en la base de datos en una sola línea.
Guardar modelo en una línea
Esto tiene su explicación; en primer lugar, al obtener el formulario en Laravel obtenemos un arreglo de datos, en donde tienen clave y valor; a través del método $request->input()
Al instanciar un modelo podemos pasar un arreglo con los datos que lo van a llenar. Ese arreglo puede ser el mismo que obtenemos desde $request->input()
Después de tener el modelo, invocamos a save
, saveOrFail
, etcétera.
Para evitar problemas de seguridad debemos tomar en cuenta que se debe definir la propiedad $fillable
del modelo, para especificar cuáles campos pueden ser llenados desde una petición HTTP o en una asignación masiva.
El modelo
Tengo un modelo de un grupo; es concretamente un grupo escolar de la escuela; por el momento solo tiene la propiedad nombre
, así que lo defino así:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Grupo extends Model
{
protected $fillable = ["nombre",
];
}
Estoy especificando que lo único fillable es el nombre.
Formulario
El formulario tiene la ruta, el método, etcétera. Aquí a cada input
le asigno, en name
, el nombre de la propiedad del modelo, misma que está en la base de datos:
<form method="POST" action="{{route("grupos.store")}}">
@csrf
<div class="field">
<label class="label">Nombre</label>
<div class="form-group">
<input autocomplete="off" name="nombre" class="form-control"
type="text" placeholder="Nombre">
</div>
<button class="btn btn-success">Guardar</button>
<a class="btn btn-primary" href="{{route("grupos.index")}}">Volver al listado</a>
</form>
Después tengo la ruta que es llamada desde el formulario; misma que llama al controlador.
El controlador: donde sucede la magia
En donde se procesa el formulario simplemente creamos el modelo y lo guardamos, sin asignar cada propiedad.
<?php
public function store(Request $request)
{
(new Grupo($request->input()))->saveOrFail();
return redirect()->back()->with(["mensaje" => "Grupo creado"]);
}
La magia está en la línea 4.
La diferencia notable
Puede que por ahora no se note o que no lo hayas entendido. Supongamos que tenemos un modelo con múltiples propiedades; manualmente se vería así:
<?php
$alumno = new Alumno;
$alumno->nombre = $request->input("nombre");
$alumno->apellido_paterno = $request->input("apellido_paterno");
$alumno->apellido_materno = $request->input("apellido_materno");
$alumno->calle = $request->input("calle");
$alumno->numero = $request->input("numero");
$alumno->localidad = $request->input("localidad");
$alumno->cp = $request->input("cp");
$alumno->save();
En cambio, con este truco, se vería así:
<?php
$alumno = new Alumno($request->input());
$alumno->save();
O en una sola línea como en el ejemplo mostrado anteriormente. Y no se afecta a la seguridad porque para eso existen los fillables.