Laravel/Eloquent:从模型内部进行验证


Laravel/Eloquent: Validation from within the model

刚刚掌握了Laravel 4.2,并且很有说服力。我一直在laracasts.com上观看Laravel from Scratch的广播,特别是关于验证和后续重构的课程。这些课程中使用的示例涉及一个相对基本的用户模型,其中只有用户名和密码两个字段。我的用户模型包含更多的字段,我的注册表要求用户重新输入/确认他们输入的密码。

似乎建议验证用户输入的过程应该在模型中完成,这是完全有意义的。因此,就像那个教程一样,我已经在我的模型中添加了一个isValid方法来验证用户在我的注册表上的输入

$input = Input::all();
if (!$this->user->fill($input)->isValid()) {
    return Redirect::back()->withInput()->withErrors($this->user->errors);
}

因此,我已经编写了规则并进行了验证,现在我可以将用户的输入保存到数据库中了。但是,由于我已经用整个用户输入填充了我的模型,用户模型实例现在包含confirm_password的属性,并且调用$user->save();会给我一个错误(因为我的数据库表中没有这个字段)。此外,由于我刚刚输入了要验证的用户输入,所以那里的密码也没有散列。

对于验证用户输入VS,让模型实际表示数据库表,最好的方法是什么?我知道有一些方法可以绕过这一切,比如将验证转移到模型之外,也许只是让模型存储验证规则等,但我可以寻求最佳实践的建议。

感谢

您可以在保存前将其删除,例如:

$input = Input::all();
if (!$this->user->fill($input)->isValid()) {
    return Redirect::back()->withInput()->withErrors($this->user->errors);
}
else {
    unset($this->user->attributes['confirm_password']);
    $this->user->save();
}

这可能有效,但不是正确的方法。您也可以使用类似于的保存event

// Goes in to your model
protected static function boot()
{
    parent::boot();
    static::saving(function($model) {
        unset($model->attributes['confirm_password']);
    });
}

由于您在模型中进行验证,因此您可能会触发saving事件的验证,例如:

protected static function boot()
{
    parent::boot();
    static::saving(function($model) {
        if($model->isValid()) {
            unset($model->attributes['confirm_password']);
            return true;
        }
        return false;
    });
}

有更好的方法来完成同样的事情。

  1. 限制输入值您可以将Input::all()传递给您的验证器,并且仍然可以执行此操作

    $input = Input::only('username', 'password');
    // – OR –
    $input = Input::except('confirm_password');
    
  2. $fillable添加到用户模型中。

    class User extends Eloquent {
        protected $fillable = array('id', 'name', 'email', 'password');
    }
    

然后,您可以从Input填充数据库,并且只填充可填充数组中的列如果你尝试这样做,请确保你有良好的验证规则

$user = User::create(Input::all());

这将在不取消设置输入值或添加模型事件的情况下完成您尝试执行的操作。