Ignore fields when updating model with Laravel & JSON

The following function should update a user’s information, while validating that the email is not duplicated and ignoring the password field if left empty. However, the function is not working.

public function update(Request $request, $id)
{
    $this->validate($request->all(), [
        'fname' => 'required',
        'email' => 'required|email|unique:users,email,'.$id,
        'password' => 'same:confirm-password',
        'roles' => 'required'
    ]);

    $input = $request->all()->except(['country_id', 'region_id']);
    if(!empty($input['password'])){ 
        $input['password'] = Hash::make($input['password']);
    }else{
        $input = array_except($input,array('password'));    
    }

    $user = User::find($id);
    $user->update($input);
    DB::table('model_has_roles')->where('model_id',$id)->delete();
    $user->assignRole($request->input('roles'));
    return response()->json(array('data' => trans('message.success')));
}

The function below is not working as expected. It should update a user’s information while validating that the email is not duplicated and ignoring the password field if left empty:

public function update(Request $request, $id)
{
    $this->validate($request->all(), [
        'fname' => 'required',
        'email' => 'required|email|unique:users,email,'.$id,
        'password' => 'same:confirm-password',
        'roles' => 'required'
    ]);

    $input = $request->all()->except(['country_id', 'region_id']);
    if(!empty($input['password'])){ 
        $input['password'] = Hash::make($input['password']);
    }else{
        $input = array_except($input,array('password'));    
    }

    $user = User::find($id);
    $user->update($input);
    DB::table('model_has_roles')->where('model_id',$id)->delete();
    $user->assignRole($request->input('roles'));
    return response()->json(array('data' => trans('message.success')));
}

The issue with the function is that the $request->all() method should not be chained with the except() method. Instead, except() should be called directly on the $request object. Additionally, the array_except() function has been deprecated since Laravel 5.3, and should be replaced with the Arr::except() method.

Here is the corrected code:

use Illuminate\Support\Arr;

public function update(Request $request, $id)
{
    $this->validate($request->all(), [
        'fname' => 'required',
        'email' => 'required|email|unique:users,email,'.$id,
        'password' => 'same:confirm-password',
        'roles' => 'required'
    ]);

    $input = $request->except(['country_id', 'region_id']);
    if(!empty($input['password'])){ 
        $input['password'] = Hash::make($input['password']);
    }else{
        $input = Arr::except($input,['password']);    
    }

    $user = User::find($id);
    $user->update($input);
    DB::table('model_has_roles')->where('model_id',$id)->delete();
    $user->assignRole($request->input('roles'));
    return response()->json(array('data' => trans('message.success')));
}