2

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.

11
  • Why are you using PATCH in update method ? and $request->input('roles') not seems to be array so the error is encountered. Commented Sep 7, 2017 at 4:21
  • $request->input('roles') can you show the vardump of this ? Commented Sep 7, 2017 at 4:24
  • I'm using PATCH because if I try with PUT or POST got methodnotallowed error Commented Sep 7, 2017 at 4:25
  • @kasper this is the var_dump string(1) "7" Commented Sep 7, 2017 at 4:25
  • @Peter can you add output of dd($request->input('roles')); ? Commented Sep 7, 2017 at 4:27

4 Answers 4

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer. I like it because of the direct update in DB query.
@Peter and no need to delete this reduce extra overhead :D
1

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

Comments

0

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');

3 Comments

Thank's for the answer but I still get the same error.
can you please elaborate the nature of roles
OK @Peter i updated the answer, Your $request->input('roles') is not an array. Please make sure it is an array
0

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');
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.