2014-01-19 173 views
10

我正在使用表单模型绑定,并使用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() }} 

它将触发我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(); 

,工作正常,但如果没有设置密码供应(因为用户不希望更新/修改),那么密码字段在数据库中设置为空。所以,如果通过表单提供新的密码值,我只想更新密码字段。

我知道我能做到以下几点:

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

但是我不知道是否有一个更清洁处理这样?像Laravel/Eloquent中的UpdateOnlyIfValueExists()方法一样。

回答

12

使用Input::only('foo', 'bar')将只抓取完成请求所需的值 - 而不是使用Input::all()

然而,如果“富”或“棒”不输入内存在,键将与null值存在:

$input = Input::only('foo', 'bar'); 
var_dump($input); 

// Outputs 
array (size=2) 
    'foo' => null 
    'bar' => null 

要在一个干净的方式进行筛选,用任何值null值:

$input = array_filter($input, 'strlen'); 

在你的榜样,这将更换:$account->fill(Input::all());

1

我会坚持你的后一个例子。另一种选择是使用mutator,它检查那里的值,如果值为空,则不更新。但在我看来,雄辩不应该为此负责。

我也避免使用所有输入与fill()。只选择你想要的。

+0

你有任何关于为什么应该避免Input :: all()的引用吗?我找不到应该避免的任何推理。 –

+0

如果您有其他可以通过批量分配填写的'User'字段,则可以使用该列名称创建任意字段,并且无需对其进行任何检查即可更改该值。仅收集您打算利用的内容是一种很好的做法。 –

+0

我明白,但正确使用模型的守护或可填充属性(我已经完成)。那么在Input :: all之间并手动填充字段本质上没有安全风险。 –

3

创建基础模型和覆盖更新功能像

/** 
* @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(); 
} 

使用后:

$model = Model::find($id); 
$model->update(Input::only('param1', 'param2', 'param3')); 
0

这是Laravel(和其他框架)相当低劣的和常见的问题。我的解决方案类似于以前的一些...

我始终将表单数据Input :: all()存储在更新/存储方法开始的变量中。由于您通常需要它至少两次(验证和创建/更新),因此这似乎是一个好习惯。然后用和做任何事情之前一样,我检查更新()输入密码的情况下,这样的:

$aFormData = Input::all(); 

if (!$aFormData['password']) 
    unset($aFormData['password']); 

... the rest of your code here using $aFormData ;) ... 

就是这样,希望它帮助!

2

检查这一点,你可以验证,如果PASSW ord存在于输入中,并将其排除在质量分配之外。您可以使用输入::除了和输入::只能用于此目的

public function update ($id) { 
    $user = User::findOrFail ($id); 
    if (Input::get ('password') == '') { 
     $user->update (Input::except ('password')); 
    } 
    else { 
     $user->update (Input::all()); 
    } 

    //return something 
} 
1
$data = $request->password ? $request->all():$request->except('password'); 
$user->update($data); 

这只会更新密码,如果它不是空

0

一个更简洁的方法是使用Eloquent Mutators

在任何情况下,您都不会允许null或空字符串作为密码,因此您可以在Account模型中安全地定义以下增变器。如果不是null和一个空字符串

// Only accept a valid password and 
// hash a password before saving 
public function setPasswordAttribute($password) 
{ 
    if ($password !== null & $password === '') 
    { 
     $this->attributes['password'] = bcrypt($password); 
    } 
} 

上述突变将只设置一个密码属性。它在保存之前还会密码保存,因此您无需在控制器操作或其他应用程序中执行此操作。

相关问题