具有唯一字段的Laravel验证服务

时间:2014-02-11 16:37:45

标签: php validation laravel-4

我正在使用验证服务来验证用户提交的表单输入(类似于http://laravel.io/bin/vrk)。

使用此方法(验证服务类)根据一组规则验证用户提交的表单数据,如何在规则具有unique规则时验证用户提交的数据。例如,如果用户的用户名为John,那么当我尝试更新模型验证失败时(因为John作为用户名存在,即使它属于当前模型)。

要在Laravel中解决这个问题,我可以做'username' => 'required|alpha_dash|unique:users,username'.$id之类的事情。我应该如何修改链接中的当前代码以最好地适应这个?我应该根据场景设置单独的验证器类(例如,UserCreateValidator,UserUpdateValidator等)。或者我应该在UserValidator类中创建单独的验证规则,并在调用UserValidator时将我想要的规则作为参数传递给构造函数或passes()方法?

4 个答案:

答案 0 :(得分:0)

嗯,你在帖子上做什么?

因为这是你应该做的事情:

$user = User::find($userId);

$user->username = $input['username'];
$user->email = $input['email'];

$user->save();

更新记录。

或者

$input = array('username' => 'w0rldart', 'email' => 'hahafu@dumbledore.com');
// Retrieve the user by the attributes, or create it if it doesn't exist, 
// based on the data above, which can come from an Input::all();
$user = User::firstOrCreate($input);

......很多可能性。但你也可以这样做:

$input = array_forget($input, 'username');

要符合您的情况,请从输入数组中删除username索引。

根据您提供给我们的信息,这就是我打电话告诉您的全部内容。如果你想要更多,请发布控制器的put方法。

更新

以下是我的PUT方法版本:http://laravel.io/bin/OaX

我真的认为try catch语法是无用的,因为很明显User模型总是在那里。但我仍然不知道你要更新什么。即使我现在无法测试它,我也不认为更新应该提供该问题,如果确实如此,则通过用户名/ id检索用户然后取消设置输入数组中的username索引,并且根据您的规格进行更新。

答案 1 :(得分:0)

我认为你可以做这样的事情

首先更新UserValidator这样的规则。

class UserValidator extends Validator {

    // Override parent class $rules
    protected $rules = [
        'default' => [
            'username' => 'required|alpha_dash|unique:users',
            'password' => 'required|between:6,16|confirmed',
            'password_confirmation' => 'required|between:6,16'
        ],
        'update' => [
            'username' => null,
        ]
    ];
} 

然后像这样修改Validator的{​​{1}}方法

passes

然后在您的控制器的public function passes($rule = null) { $rules = $this->rules['default']; if ($rule && isset($this->rules[$rule])) { $rules = array_merge($rules, $this->rules[$rule]); } $validator = \Validator::make($input, $rules); if ($validator->fails()) { $this->validator = $validator; return false; } return true; } 方法中,这会将PUT规则合并到update规则

default

您无需更改控制器的$rule = 'update'; // user has changed his username if ($input['username'] !== $old_username) { $rule = 'create'; // validate uniqueness } else { unset($input['username']); // remove it, we don't validate it anymore since it's the same } $validator->passes($rule); // override 'default' rules with 'update' rules 方法,它将保持不变

POST

答案 2 :(得分:0)

如果我理解正确,由于模型的主键约束,您在更新数据时遇到问题。您需要做的是创建两组规则,一组用于插入,一组用于更新。

假设你有一套这样的规则:

protected $rules = [
'id' => 'required|unique:users'
]

你应该实现这样的东西:

protected $rules = [
'id' => 'required|unique|unique:users,id,' . $this->id
];

这应该告诉laravel忽略表用户中指定id的重复id,在这种情况下,是当前对象的id。

您可以在http://laravel.com/docs/validation

上阅读有关laravel文档的更多信息
  

唯一:表,列,除了,idColumn

     

验证字段在给定数据库表上必须是唯一的。   如果未指定列选项,则将使用字段名称。

答案 3 :(得分:0)

UserValidator

中的一点修改
class UserValidator extends Validator {

    // Override parent class $rules
    protected $rules = [
        'username' => 'required|alpha_dash|unique:users',
        'password' => 'required|between:6,16|confirmed',
        'password_confirmation' => 'required|between:6,16'
    ];

    // ADD THIS
    public function __construct(Array $rules = array())
    {
        parent::__construct();
        if(count($rules)){
            foreach($rules as $k => $v) $this->rules[$k] = $v;
        }
    }
}    

在您的控制器putUpdate方法

$user = User::whereUsername($username)->firstOrFail();
$rules = ['username' => 'required|alpha_dash|unique:users,username,'. $user->id];
// Pass the rule to update the rule for username in this method
$validator = \Services\Validators\UserValidator(Input::all(), $rules);

检查the manual here