【问题标题】:Stripping empty attributes from Laravel model before saving在保存之前从 Laravel 模型中剥离空属性
【发布时间】:2015-05-29 08:21:18
【问题描述】:

我正在尝试从表单中删除所有被提交到我的数据库中的空字段(使用 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)没有影响;我想我只是错过了一些明显的东西,我的 [当前] 隧道视野不会让我看到。

【问题讨论】:

    标签: php laravel laravel-5


    【解决方案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 方法。
    • @ShazAmjad 应该有。你使用的包是jenssegers/laravel-mongodb,对吧?他们确实扩展了基本模型:abstract class Model extends \Illuminate\Database\Eloquent\Model { 然后Jenssegers\Mongodb\Model 具有abstract class Model extends \Jenssegers\Eloquent\Model {。你得到了什么错误?
    • 是的,就是这样 - 没有错误,什么都没有。我在Base 模型的static::saving 中尝试了return false,但模型仍然保存任何更新的数据;这就是为什么我想知道如何最好地检查 MyModel 是否实际上使用父 Base 模型的 boot 方法...
    • 无处不在的dd 怎么样?打开 Moloquent 模型并在其中转储一些 dd() 并检查调用的内容和未调用的内容。
    • 非常奇怪 - 我无法在基本模型和扩展模型中获得 boot() 中的任何模型事件。
    【解决方案2】:

    对于任何前来寻找解决方案的人;我设置了一个中间件来去除所有空输入字段,然后在保存方法中做了同样的事情。

    /* 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()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多