Cuando definimos nuestra base de datos, a veces es necesario tener campos cuyos valores están en función de otros valores del mismo registro o en función de valores predefinidos.
Por ejemplo, si se define una tabla PRODUCTS que tiene una columna CODE y se quiere que el valor de esta columna code sea en función a la categoría al que pertenece el producto y que sea ascendente de uno en uno; o que el precio sea el 40% superior al costo. En la creación del registro se utilizaría un proceso como el siguiente:
public function store(ProductRequest $request)
{
$productCode = $request->category_id*10000 + Product::max('id') + 1;
$price = $request->cost * 1.4;
Product::create([
'code' => $productCode,
'name' => $request->name,
'cost' => $request->cost,
'price' => $price
]);
return redirect( route('products.index') )
->with('message', __("Producto registrado correctamente"));
}
En otros casos, los cálculos pueden ser más complejos que este, cosa que implica que aumenten las líneas de código, que los controladores sean más extensos o que sea se caiga en código repetitivo si se necesita que la acción se reproduzca en otros controladores.
Para evitar este tipo de casos, Laravel provee la función boot() que se define en los respectivos modelos.
Para este caso se podría hacer de la siguiente manera, definiendo la función en el modelo:
class Product extends Model
{
protected static function boot()
{
parent::boot();
Product::creating(function($model) {
$model->code = request('category_id')*10000+Product::max('id')+1;
$model->price = request('cost') * 1.4;
});
}
.
.
.
}
Lo que le indica al sistema que al momento de crear el producto los campos code y price van a ser calculados automáticamente en función de ciertos valores ya dados.
Y en el controlador o controladores el proceso únicamente quedaría:
public function store(ProductRequest $request)
{
Product::create([
'name' => $request->name,
'cost' => $request->cost,
]);
return redirect( route('products.index') )
->with('message', __("Producto registrado correctamente"));
}
Nótese que ahora no es necesario definir los valores de los campos price y cost en el controlador.