在保存Laravel模型之前,剥离空属性

3

我正在尝试从表单中剥离所有空字段,以防止它们被提交到我的数据库中(使用Mongo - Moloquent扩展Eloquent)。

我有一个基本模型:

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;
    });
  }
}

然后扩展它:

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

但是它对子类(MyModel)没有影响;我认为我只是错过了一些明显的东西,我的[当前]隧道视野让我看不到。
2个回答

1

Eloquent的基础模型有一个名为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();
}

如果Moloquent扩展了这个类或者有一个类似这样的方法,你可以在过滤属性数组后使用它,例如:
$model->setRawAttributes(array_filter($model->getAttributes()));

这个不起作用 - 就好像 MyModel 实际上没有扩展 Base / 使用父级 boot 方法一样。 - Shaz MJ
@ShazAmjad 应该有的。您使用的包是 jenssegers/laravel-mongodb,对吧?他们扩展了基本模型:abstract class Model extends \Illuminate\Database\Eloquent\Model { 然后 Jenssegers\Mongodb\Modelabstract class Model extends \Jenssegers\Eloquent\Model {。您遇到了什么错误? - hfingler
是的,就是那个 - 没有错误,什么也没有。我在 Base 模型的 static::saving 中尝试了 return false,但模型仍然保存了任何更新的数据;这就是为什么我想知道如何最好地检查 MyModel 是否实际上正在使用父级的 Base 模型的 boot 方法... - Shaz MJ
用好老的dd怎么样?打开Moloquent模型,放入一些dd()并检查正在调用什么和未调用什么。 - hfingler
难以置信的奇怪 - 我无法获取boot()中任何模型事件,无论是在基础模型还是扩展模型中。 - Shaz MJ
所有错误中最愚蠢的错误;我的 constructor 缺少了 parent::__constructor。我的原始方法现在可以使用了,但是 ->setRawAttributes() 在 mongo 中不能很好地工作;我必须使用 ->unset($key) - Shaz MJ

0
任何寻找解决方案的人士,我设置了一个中间件来删除所有空输入字段,然后在保存方法中执行相同操作。
/* app/Http/Middleware/StripRequest.php */

use Closure;
class StripRequest {
  public function handle($request, Closure $next)
  {
    $request->replace(array_filter($request->all()));
    return $next($request);
  }
}

记得将其添加到内核的$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',
];

从那里开始,我使用了与上面指定的相同的模型。只需记住在您的构造函数中使用parent::__construct()或在任何其他方法中调用父级即可。对我有效的方法是:

/* 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;
});

我使用了 https://github.com/jenssegers/laravel-mongodb#mongodb-specific-operations 中的 unset() 函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接