Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

bottelet's avatar

User permission frontend

Hello Laracast

Im trying to make it some the admin can decied which role can do what, from the frontend easily, but i'm a bit stuck. I've tried a couple of diffrent things, but none of the worked so far. I've tried this so far:

Controller
$PermissionRole = PermissionRole::all();
return view('settings.index')->withPermissionRole($PermissionRole);

View
    @foreach($permission_role as $emprole)
    @if($emprole->role_id == 3 || $emprole->permission_id = 1)
    YES
    @else
    NO
    @endif
    @endforeach

But of course that wont work, as it just goes thourgh all of the rows obviously. I'am a bit unclear on what approach i should take. I have the following Tables:

Permission_role
 * Role_id
 * Permmission_id
Permission
 * Name
 * Slug
* Description
Roles
 * Name
 * Slug
* Description
Role_user
 * role_id
 * user_id

The thing is i wanna update all theese rows at once, so the user dosen't have to save for each change. Any advice would be great!

Edit still haven't figured this out, updated my code in new post.

0 likes
15 replies
ricardovigatti's avatar

That's the logic to render all roles, and inside each one, render all permissions.

@foreach($roles as $role) 
{
    @foreach($permissions as $permission)
    {
        // do stuffs
    }
}

But i think you are missing some theories from relationship with eloquent. You are not using any third party package for roles&permissions, are you? If not, you should consider to use one.

bottelet's avatar

@ricardovigatti Thanks i will test it, i am useing Laravel rbac from phpzen. One of my problems with the foreach is aswell, when i detach a permission from the role, i wont be able to attach it again because it is removed from the DB

ricardovigatti's avatar

I don't know if you are understanding the things right. I see you trying to loop the data from PermissionRole::all();. But Permission_role is a pivot table, you don't need to create a Model for it.

Instead, you need to get all roles and all permissions, you can use:

$roles = Role::all();
$permissions = Permission::all();

Now, in your view, you can run the loops.

In addition: https://laravel.com/docs/5.0/eloquent#relationships

Sorry if I'm not understanding you right.

bottelet's avatar

Ah of course, dont know why i would treat it as a "primary table". But now that i show all the permissions, with an foreach, how would i go about updating the row too the Permissons_role. Could i do something like this

        @foreach($role as $role) 
                {{$role->name}} <br />
    @foreach($permission as $perm)
       {{$perm->description}} <br />
         {!! Form::select('get_the_id_from_permissons_role_here?', [1 => 'Allowed', 2 => 'Not Allowed'], $settings->task_complete_allowed, ['class' => 'form-control']) !!}
    @endforeach

    @endforeach

I dont really know how that would work, as the id of the field would be the same for all them?

@ricardovigatti Sorry for all the questions, i am bit confused I'll ahve to admit

ricardovigatti's avatar

No problem man... Create a form to manage permissions is very complicated and needs attention.

Now that you have all permissions listed for a given role, it's time to assign the form fields you need to update it all. Maybe you're trying to make a single form request, but i can suggest u to create various forms, according to your roles. This means that we should have one form for each role. Inside each form, we should have a hidden field responsible to identify the role. It's hard to explain, but try to figure out according to the code above:

@foreach($roles as $role)
    <form>
        {{$role->name}} <br />
        <input type="hidden" name="role_id" value="{{ $role->id }}" />

        @foreach($permissions as $perm)
            {{$perm->description}} <br />
            <select name="permissions[ {{ $perm->id }} ]">
                <option value="1">Allowed</option>
                <option value="0">Not Allowed</option>
            </select> <br />
        @endforeach 

        <input type="submit" value="Send" />
    </form>
@endforeach 
bottelet's avatar

Yeah i got to something simillar aswell, i guess my problem is how do in the controller do it so if at employee create.client(Permission) is unchecked, then detatch the permission from the employee role, and keep it detacthed so the Admin won't have to click it off everytime they change some setting.

  public function permmisionsupdate()
    {
        If requested field is checked...
        Attach permission to Role
    If requested field is not checked...
    dettach permission to Role
    }

@ricardovigatti Thanks for the help so far!

ricardovigatti's avatar

Yeah, that's the next step. In your "view" we need to set the value for each permission, according to the role. I don't know how works the package you are using . In my case, i have a package that use the same database structure as yours, and i can check if a given role can perform some action using this code:

$role = Role::find($role_id);
$role->can($permission_slug); // returns true or false

I'll use this to display my data inside the view. You can adapt it.

@foreach($roles as $role)
    <form>
        {{$role->name}} <br />
        <input type="hidden" name="role_id" value="{{ $role->id }}" />

        @foreach($permissions as $perm)
            {{$perm->description}} <br />
            <select name="permissions[ {{ $perm->id }} ]">
                <option value="1" {{ $role->can($perm->slug) ? 'selected="selected"' : null }}>Allowed</option>
                <option value="0" {{ $role->can($perm->slug) ? null : 'selected="selected"' }}>Not Allowed</option>
            </select> <br />
        @endforeach 

        <input type="submit" value="Send" />
    </form>
@endforeach

Now your "view" always will represent correctly the data from your database.

In your controller, we simply need to get the posted data and save them. In my case, i can use a method called "syncPermissions()", who delete all "role_permissions" data, then assign again. Remember we added an input hidden with the role id ? We are going to use it now:

public function permissionsUpdate(Request $request)
{
    $allowed_permissions = [];

    // we want only allowed permissions from the request, so we filter it
    foreach($request->input('permissoes') as $permission) {
        if ($permission == 1) {
            $allowed_permissions[] = $permissions;
        }
    }

    $role = Role::find($request->input('role_id'));
    $role->syncPermissions($allowed_permissions);
    $role->save();
}
bottelet's avatar

It seems like i'm getting closer I'm getting the correct values etc. But on the Sync i am getting the following error:

BadMethodCallException in Builder.php line 2161:
Call to undefined method Illuminate\Database\Query\Builder::syncPermission()

But I'm not sure i can do it like this 100% because at the drop down, it assigns the valuve 1 or 0... and where does theese valuves get inserted? I really appreciate the help @ricardovigatti But i have to admit i am abit lost.

bottelet's avatar

I could still use some help with this if anyone else has some suggestion...

This is my current code: View

        @foreach($role as $role) 
                 {!! Form::model($permission, [
        'method' => 'PATCH',
        'url'    => 'settings/permissionsUpdate',
        ]) !!}
              <br />  {{$role->name}} <br />
              <input type="hidden" name="role_id" value="{{ $role->id }}" />
    @foreach($permission as $perm)
      
                 <select name="permissions[ {{ $perm->id }} ]">
                <option value="1">Allowed</option>
                <option value="0">Not Allowed</option>
            </select> <br />
     
     
      {{$perm->name}}<br />
    @endforeach
       
{!! Form::submit('Save Settings', ['class' => 'btn btn-primary']) !!}
  {!! Form::close() !!}
    @endforeach

Models

Role:

public function permissions()
{
    return $this->hasMany('permissions');
}

Permission

public function PermissionsRole()
{
    return $this->hasMany('App\PermissionRole', 'role_id', 'id');
}

Controller:

    public function permissionsUpdate(Request $request)
    {
        $allowed_permissions = [];

        foreach($request->input('permissions') as $permission) {
        if ($permission == 1) {
            $allowed_permissions[] = $permission;
        }
        $role = Role::find($request->input('role_id'));
        $role->permissions()->sync($allowed_permissions);
        $role->save();
    }

    }
bottelet's avatar

@ricardovigatti I had the problem of my Model being wrong, it tried to finde table role_role so i changed it to

    public function permissions()
    { 
        return $this->belongsToMany('App\permission'); (Had to make a new model called permission, because when i used permissions it loked for role_permissions and it is called role_permission, but the table alone is called permissions, bit confsuing there)
    }

And that almost made it work, but It only changes the first value(1) Even if all are on allowed it only attaches the permissons_id equal to 1 and then role id equal to the correct role_id, if i dd the Request it seems to get all the correct data with permission_id = 1, 2 ,3 ,4, but it goes wrong somewhere after that. Also the view still dosen't show which is allowed or not from start. Coulndt get it to work, i tried something like:

<option value="1" {{ @ifUserCan($perm->slug)@endif  ? 'selected="selected"' : null }} >Allowed</option>
<option value="0" {{ @ifUserCan($perm->slug) ? null : 'selected="selected"' @endif }}>Not Allowed</option>

But yeah you can't do that.

bottelet's avatar

@ricardovigatti I did above

    public function permissions()
    { 
        return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
    }

In my Role Model But im still only editing the first value, its only asserting role_id = 1 into the DB with the correct user_id.. But it's not adding role_id 1,2,3,4,5,6 etc...

bottelet's avatar

I tried this:

    public function permissionsUpdate(Request $request)
    {
        $allowed_permissions = []; 
        
        foreach($request->input('permissions') as $permission) {
        if ($permission == 1) {
            $allowed_permissions[] = $request->input('permissions');
            
             
        }
        
        }
    $role = Role::find($request->input('role_id'));
       $role->permissions()->sync($allowed_permissions);
        $role->save();
   

    }

But can't really do it like that, getting the following error

QueryException in Connection.php line 651:
SQLSTATE[42S22]: Column not found: 1054 Unknown column ' 1 ' in 'field list' (SQL: insert into `role_user` (` 1 `, ` 10 `, ` 2 `, ` 3 `, ` 4 `, ` 5 `, ` 6 `, ` 7 `, ` 8 `, ` 9 `, `role_id`, `user_id`) values (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1))

Please or to participate in this conversation.