我正在使用验证服务来验证用户提交的表单输入(类似于http://laravel.io/bin/vrk)。
使用此方法(验证服务类)根据一组规则验证用户提交的表单数据,如何在规则具有unique
规则时验证用户提交的数据。例如,如果用户的用户名为John
,那么当我尝试更新模型验证失败时(因为John
作为用户名存在,即使它属于当前模型)。
要在Laravel中解决这个问题,我可以做'username' => 'required|alpha_dash|unique:users,username'.$id
之类的事情。我应该如何修改链接中的当前代码以最好地适应这个?我应该根据场景设置单独的验证器类(例如,UserCreateValidator,UserUpdateValidator等)。或者我应该在UserValidator
类中创建单独的验证规则,并在调用UserValidator时将我想要的规则作为参数传递给构造函数或passes()
方法?
答案 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);