简体   繁体   中英

Laravel form doesn't update values in database instead is delete them

I have form where I can change user role. When I try to change and hit Save button I've got invalid foreach() argument error and previous record in database for this user is deleted completely.

This is my form

{!! Form::model($user, ['method' => 'PATCH','route' => ['admin.addper', $user->user_id]]) !!}
<div class="row">
    <div class="col-md-4 col-xs-12">
         <div class="form-group">
             <label for="title" class="control-block">Username:</label>
                {{ Form::text('username', $user->username, ['class' => 'form-control', 'disabled']) }}
         </div>
    </div><!-- end col-4/12 -->
    <div class="col-xs-12 col-md-8">
         <div class="form-group">
            <label for="title" class="control-block">Choose which Role you want to assign to user:</label><br>
                @foreach($roles as $value)
                    {{ Form::checkbox('roles', $value->id, in_array($value->id, $userRole) ? true : false, array('class' => 'name')) }}
                        <strong>{{ $value->display_name }}</strong> 
                        <br/>
                @endforeach
         </div>
    </div>
    <div class="col-xs-12 col-sm-12 col-md-12 text-center">
            <button type="submit" class="btn btn-primary">Submit</button>
    </div>
</div>
{!! Form::close() !!}

And this is the controller part

public function update(Request $request, $id)
{
    $this->validate($request, [
        'roles' => 'required'
    ]);

    $input = $request->all();
    $user = User::find($id);
    $user->update($input);
    DB::table('role_user')->where('user_id',$id)->delete();

    foreach ($request->input('roles') as $key => $value) {
        $user->attachRole($value);
    }

    return redirect()->route('users')
                    ->with('success','User Role Updated Successfully');
}

The error is on the foreach in the controller

ErrorException: Invalid argument supplied for foreach()

Since I'm sure that I pass correct user_id and correct value of role_id why is this error?

dd($request->input('roles'));

return correct id which I'm choose on checkbox.

I assume your roles is an array. Then use

foreach ($request->input('roles') as $value)
{
    $user->attachRole($value);
}

The reason is you have only a single value to the id, not an associative array. So you are trying to use invalid parameter for foreach

If your roles is not an array make it an one.

This method allows use to keep more than 1 role.

For example to make your $request->input('roles') an array try with

if(!is_array($input->request('roles')))
    $roles[] = $input->request('roles');

You are getting role as string not as array so directly assign it without loop

DB::table('role_user')->where('user_id',$id)->delete();
$value = $request->input('roles');
$user->attachRole($value);

You need to delete the existing role and attach the new one like this:

DB::table('role_user')->where('user_id',$id)->delete();
$user->attachRole($request->input('roles'));

I think you have single role in the role_user table for each user, so you can use find and update method as well.

Like,

DB::table('role_user')
   ->where('user_id',$id)
   ->update(['role' => $request->input('roles')]);

This way will reduce extra overhead of unnecessary delete and with just single query you can update role of the user.

I hope you have understood.

The reason you had that error because in your view you have defined the roles as a single valued input. You need to add [] to the name of your input.

{{ Form::checkbox('roles[]', $value->id, in_array($value->id, $userRole) ? true : false, array('class' => 'name')) }}

Then you can access roles like an array in your controller. But you need to check for the existence of roles or pass a default value as it is not sent to the server if every checkbox is unchecked.

 foreach ($request->input('roles', []) as $role) {
      $user->attachRole($role)
 }

Or you can leverage Eloquent and define a roles relationship in your user model.

public function roles()
{
    return $this->belongsToMany('roles');
}

and in your controller

public function update(Request $request, $id)
{
    $this->validate($request, [
        'roles' => 'required'
    ]);

    $user = User::find($id);
    $user->update($request->all());

    $user->roles()->sync($request->input('roles', []));

    return redirect()->route('users')
                    ->with('success','User Role Updated Successfully');
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM