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

warpig's avatar
Level 12

How to assign an ability to a role?

On the front end Im able to create a role and an ability but I want to be able to assign abilities via the front end to a role?

On Tinker I have to run this to create a new role:

$moddy = App\Models\Role::firstOrCreate(['name' => 'moddy']);

Creating a new ability on tinker:

 $view_videos = App\Models\Ability::firstOrCreate(['name' => 'view_videos']);

How do I get to assign an ability to a role? This is how I do it through tinker;

$moddy->allowTo($view_videos);

This is my view:

@foreach ($roles as $role)
    <div>
        <p>{{ $role->name }}</p>
        
        <form 
            action=""
            model="POST"
        >
            <select 
                name="abilities" 
                id="abilities"
                multiple
            >
                @foreach ($abilities as $ability)
                    <option value="{{ $ability->id }}">
                        {{ $ability->name }}
                    </option>
                @endforeach
            </select>

            <button type="submit">
                Assign
            </button>
        </form>
    </div>
@endforeach
0 likes
4 replies
tykus's avatar
tykus
Best Answer
Level 104

Make the field name an array

 <select 
                name="abilities[]" 
                id="abilities"
                multiple
>

Now, whenever you submit the form, you will get an array of abilities IDs in the Request, so you can iterate:

foreach ($request->abilities as $ability) {
	$role->allowTo($ability); // if you can pass an id
}

Otherwise, if allowTo must receive a Model instance:

$abilities = App\Models\Ability::find($abilities); // returns a Collection

$abilities->each(fn ($ability) => $role->allowTo($ability));
warpig's avatar
Level 12

Using it like this:

    public function __invoke(Request $request, Role $role, Ability $abilities)
    {   
        $abilities = Ability::find($abilities);

        $abilities->each(fn ($ability) => $role->allowTo($ability));

        return redirect()->route('assignAbility');
    }

Returns this message:

The GET method is not supported for this route. Supported methods: POST. 

But the route is POST as well as the method on the form.

    Route::post('/assignAbility', AbilitiesRoleController::class)->name('assignAbility');

Full error: https://flareapp.io/share/DPyZJkJ7

Quick reminder

  1. Always add @csrf token to your forms, if not you will experience the 419 server error
  2. In this situation having this line: return redirect()->route('assignAbility'); was causing the method to perform a GET request, which wasn't what I was expecting since I only wanted to go back to the same page.

Also using the same route name that I was already using to perform the POST method wasn't a good idea.

Question was this: How to assign an ability to a role?

The context was via the front-end, for that you must:

  1. Expect a variable in the URI, in my case {role} so an existing role is taken in consideration
  2. Accept it on the form and method so that you can process the request to the server
  3. Once in the method you should be able to use any relationship that you might have, it helps if you watch something like this: https://laracasts.com/series/laravel-6-from-scratch/episodes/54
warpig's avatar
Level 12

Solved it with this line: return redirect()->back();

tykus's avatar

Not really related to the original question though, is it?

Please or to participate in this conversation.