Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Only update field if form value exists

I'm using Form Model Binding as such and updating my DB using the fill() and save() methods.

{{ 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:

$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.

like image 992
Michael Pasqualone Avatar asked Jan 19 '14 21:01

Michael Pasqualone


5 Answers

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'));
like image 118
mrsum Avatar answered Nov 18 '22 15:11

mrsum


Using Input::only('foo', 'bar') will grab only the values needed to complete the request - instead of using Input::all().

However, if 'foo' or 'bar' doesn't exist within the input, the key will exist with the value of 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:

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

In your example, this would replace: $account->fill(Input::all());

like image 34
acairns Avatar answered Nov 18 '22 17:11

acairns


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

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

    //return something
}
like image 2
IAmJulianAcosta Avatar answered Nov 18 '22 16:11

IAmJulianAcosta


$data = $request->password ? $request->all():$request->except('password');
$user->update($data);

This will only update the password if it's not null

like image 2
Faran Ali Avatar answered Nov 18 '22 15:11

Faran Ali


I would stick with your latter example. Another option would be to use a mutator which 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.

I'd also avoid using ALL input with fill(). Choose only what you want.

like image 1
Aken Roberts Avatar answered Nov 18 '22 17:11

Aken Roberts