1

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

似乎建议验证用户输入的过程应在模型内完成,这完全有意义。所以就像那个教程一样,我继续isValid往我的模型中添加了一个方法来验证我的注册表单上的用户输入。我根据这样的输入填充我的用户模型:

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

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

关于验证用户输入 VS 让模型实际代表数据库表,最好的方法是什么?我知道有一些方法可以解决所有这些问题,例如将验证移到模型之外,也许只是让模型存储验证规则等,但我可以寻求有关最佳实践的建议。

谢谢

4

2 回答 2

2

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

$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;
    });
}
于 2014-09-21T17:53:49.180 回答
2

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

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

这将完成您尝试执行的操作,而无需取消设置输入值或添加模型事件。

于 2015-01-15T03:55:16.907 回答