2014-01-19 178 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); 
    } 
} 

上述突變將只設置一個密碼屬性。它在保存之前還會密碼保存,因此您無需在控制器操作或其他應用程序中執行此操作。

相關問題