Shaz Ravenswood
Shaz Ravenswood

Reputation: 1835

Stripping empty attributes from Laravel model before saving

I'm trying to strip all empty fields from being submitted into my database from the form (using Mongo - Moloquent extends Eloquent).

I've got a base 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 extend it:

class MyModel extends Base{
  public static function boot(){
    parent::boot()
  }
}

But it has no effect on the child class (MyModel); I think I'm just missing something obvious that my [current] tunnel vision won't let me see.

Upvotes: 3

Views: 2317

Answers (2)

Shaz Ravenswood
Shaz Ravenswood

Reputation: 1835

For anyone else who comes looking for a solution; I setup a middleware to strip out all empty input fields, and then did the same in the saving 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);
  }
}

Remember to add it in 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 as specified above. Just remember to use parent::__construct() in your constructors or call parent in any other methods. The 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

Upvotes: 0

hfingler
hfingler

Reputation: 2004

Eloquent's base model has a method called setRawAttributes:

/**
 * 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 attributes array, like:

$model->setRawAttributes(array_filter($model->getAttributes()));

Upvotes: 1

Related Questions