laravel 如果表单值存在,则仅更新字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21222964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Only update field if form value exists
提问by Michael Pasqualone
I'm using Form Model Binding as such and updating my DB using the fill() and save() methods.
我正在使用表单模型绑定,并使用 fill() 和 save() 方法更新我的数据库。
{{ Form::model($account) }}
{{ Form::text('name', null, array('class'=>'class')) }}
{{ Form::text('email', null, array('class'=>'class')) }}
{{ Form::password('password', array('class'=>'class')) }}
{{ Form::password('password_confirmation', array('class'=>'class')) }}
{{ Form::close() }}
Which fires my editAccount controller method:
这会触发我的 editAccount 控制器方法:
$rules = array(
'name' => array('required'),
'email' => array('required'),
'password' => array('confirmed')
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
// Redirect
}
// Save to DB
$account->fill(Input::all());
$account->save();
Which works fine, but if no password was supplied (because the user doesn't want to update/modify it) then the password field is set to null in the db. So, I only want the password field to update if a new password value is supplied via the form.
这工作正常,但如果没有提供密码(因为用户不想更新/修改它),那么密码字段在数据库中设置为空。因此,如果通过表单提供了新的密码值,我只希望密码字段更新。
I know I can do the following:
我知道我可以做到以下几点:
// Set the fields manually
$account->name = Input::get('name');
$account->email = Input::get('email');
// Only update the password field if a value is supplied
if (Input::get('password')) {
$account->password = Input::get('password');
}
$account->save();
However I'm wondering if there is a more cleaner way to handle this? Like an UpdateOnlyIfValueExists() method within Laravel/Eloquent.
但是我想知道是否有更清洁的方法来处理这个问题?就像 Laravel/Eloquent 中的 UpdateOnlyIfValueExists() 方法。
采纳答案by acairns
Using Input::only('foo', 'bar')
will grab only the values needed to complete the request - instead of using Input::all()
.
UsingInput::only('foo', 'bar')
将仅获取完成请求所需的值 - 而不是使用Input::all()
.
However, if 'foo' or 'bar' doesn't exist within the input, the key will exist with the value of null
:
但是,如果输入中不存在 'foo' 或 'bar',则键值将存在null
:
$input = Input::only('foo', 'bar');
var_dump($input);
// Outputs
array (size=2)
'foo' => null
'bar' => null
To filter in a clean way, any values with a null
value:
要以干净的方式过滤任何具有null
值的值:
$input = array_filter($input, 'strlen');
In your example, this would replace: $account->fill(Input::all());
在您的示例中,这将替换: $account->fill(Input::all());
回答by mrsum
Create Base model and override update function like
创建基础模型并覆盖更新功能,如
/**
* @param array $attributes
* @return mixed
*/
public function update(Array $attributes = array()){
foreach($attributes as $key => $value){
if(!is_null($value)) $this->{$key} = $value;
}
return $this->save();
}
After use:
使用后:
$model = Model::find($id);
$model->update(Input::only('param1', 'param2', 'param3'));
回答by IAmJulianAcosta
Check this, you can validate if password is present in input, and exclude it from mass assignment. You can use Input::except and Input::only for this purpose
检查这一点,您可以验证输入中是否存在密码,并将其从批量分配中排除。您可以为此目的使用 Input::except 和 Input::only
public function update ($id) {
$user = User::findOrFail ($id);
if (Input::get ('password') == '') {
$user->update (Input::except ('password'));
}
else {
$user->update (Input::all ());
}
//return something
}
回答by Faran Ali
$data = $request->password ? $request->all():$request->except('password');
$user->update($data);
This will only update the password if it's not null
如果密码不为空,这只会更新密码
回答by Aken Roberts
I would stick with your latter example. Another option would be to use a mutatorwhich checks the value there, and doesn't update if the value is empty. But in my opinion, Eloquent should not be responsible for doing that.
我会坚持你的后一个例子。另一种选择是使用一个mutator来检查那里的值,如果值为空则不更新。但在我看来,Eloquent 不应该为此负责。
I'd also avoid using ALL input with fill()
. Choose only what you want.
我也会避免将所有输入与fill()
. 只选择你想要的。
回答by rei
This is a pretty shitty and common issue with Laravel (and other frameworks). My solution resembles some of the previous...
这是 Laravel(和其他框架)的一个非常糟糕且常见的问题。我的解决方案类似于以前的一些...
I always have the form data Input::all() stored in a variable at the beginning of the update/store methods. Since you usually need it at least twice (validate and create/update) it seems like a good practice. Then with that and before doing anything else I check in update() for the presence of the password, something like this:
我总是在更新/存储方法开始时将表单数据 Input::all() 存储在一个变量中。由于您通常至少需要它两次(验证和创建/更新),这似乎是一个很好的做法。然后在做任何其他事情之前,我检查 update() 是否存在密码,如下所示:
$aFormData = Input::all();
if ( !$aFormData['password'] )
unset( $aFormData['password'] );
... the rest of your code here using $aFormData ;) ...
And that's it, hope it helps!
就是这样,希望它有帮助!
回答by Noman Ur Rehman
A much cleaner approach would be to use Eloquent Mutators
更简洁的方法是使用Eloquent Mutators
Under no circumstances would you allow a null
or an empty string as password so you can safely define the following mutator in your Account
model.
在任何情况下,您都不允许使用 anull
或空字符串作为密码,因此您可以安全地在Account
模型中定义以下修改器。
// Only accept a valid password and
// hash a password before saving
public function setPasswordAttribute($password)
{
if ( $password !== null & $password === '' )
{
$this->attributes['password'] = bcrypt($password);
}
}
The above mutator will only set a password attribute if it is not null
and an empty string. It also hashes the password before saving so you do not need to do it in your controller action or application elsewhere.
上面的 mutator 只会设置一个密码属性,如果不是,null
并且是一个空字符串。它还会在保存之前对密码进行哈希处理,因此您无需在其他地方的控制器操作或应用程序中执行此操作。
回答by Chris
Best approche is to use mutators as Noman Ur Rehman said above, but he had mistake in his code. Right one will be:
最好的方法是使用上面提到的 Noman Ur Rehman 的 mutators,但他的代码有错误。正确的将是:
public function setPasswordAttribute($password){
if ( $password !== null && $password !== '' )
$this->attributes['password'] = Hash::make($password);
}