Disabling empty attributes from Laravel model before saving
I am trying to remove all empty fields from my database from a form (using Mongo - Moloquent extends Eloquent).
I have a basic model:
class Base extends Moloquent {
public static function boot(){
parent::boot();
static::saving( function($model){
$arr = $model->toArray();
$removed = array_diff($arr, array_filter($arr));
foreach($removed as $k => $v) $model->__unset($k);
return true;
});
}
}
And then continue it:
class MyModel extends Base{
public static function boot(){
parent::boot()
}
}
But this does not affect the child class (MyModel); I think I'm just missing something obvious that my tunnel vision won't let me see.
source to share
For anyone looking for a solution; I am installing middleware to strip out all empty input fields and then did the same in the save method.
/* app/Http/Middleware/StripRequest.php */
use Closure;
class StripRequest {
public function handle($request, Closure $next)
{
$request->replace(array_filter($request->all()));
return $next($request);
}
}
Do not forget to add it to the kernel $middleware
:
/* app/Http/Kernel.php */
protected $middleware = [
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
'app\Http\Middleware\StripRequest',
];
From there I used the same models above. Don't forget to use parent::__construct()
in your constructors or call the parent in other methods. Method that worked for me:
/* app/Models/Base.php */
static::saving(function($model){
// Clear out the empty attributes
$keep = array_filter($model->getAttributes(), function($item){ return empty($item); });
foreach($keep as $k => $v) $model->unset($k);
// Have to return true
return true;
});
I used unset()
from https://github.com/jenssegers/laravel-mongodb#mongodb-specific-operations
source to share
The striking base model has a setRawAttributes method:
/**
* Set the array of model attributes. No checking is done.
*
* @param array $attributes
* @param bool $sync
* @return void
*/
public function setRawAttributes(array $attributes, $sync = false)
{
$this->attributes = $attributes;
if ($sync) $this->syncOriginal();
}
If Moloquent extends this class or has a method like this, you can use it after filtering the array of attributes, for example:
$model->setRawAttributes(array_filter($model->getAttributes()));
source to share