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

kieranjfahy's avatar

Gate auth in loops

I have multiple forloop's inside my project and I am using @can to check if the person has the ability to edit or update etc to each item. However this produce a gate check for each row. Can anyone suggest how I would check the abilities of a user once rather than for each line. Or, is the over head for this check worth worrying about?

Here is a code sample:

@foreach($routes as $route)
                                    <tr>
                                        <td><strong> {!! $route->id !!}</strong></td>
                                        <td><strong> {!! $route->zone->zone !!}</strong></td>
                                        <td><strong> {!! $route->route_number !!}</strong></td>
                                        <td><strong> {!! $route->end_time_am !!}</strong></td>
                                        <td>{!! $route->end_point_am !!}</td>
                                        <td>{!! $route->start_time_pm !!}</td>
                                        <td>{!! $route->start_point_pm !!}</td>
                                        <td>{!! $route->end_time_pm !!}</td>
                                        @can('update', $route)
                                            <td class="hidden-xs" style="width:2%;">
                                                <a title="Edit"
                                                   href="{!! URL::route('update_route', $route->id) !!}"
                                                   class="pull-right"><i class="fa fa-pencil-square-o fa"></i>
                                                    <a>
                                            </td>
                                        @endcan
                                        @can('update', $route)
                                            <td class="hidden-xs" style="width:2%;">
                                                <a title="Remove"
                                                   href="{!! URL::route('remove_route', $route->id) !!}"
                                                   class="pull-right"><i class="fa fa-times"></i>
                                                    <a>
                                            </td>
                                        @endcan
                                    </tr>
                                @endforeach 
0 likes
5 replies
zachleigh's avatar

Why check twice? Its the exact same check so just put it in one block:


@foreach($routes as $route)
    <tr>
        <td><strong> {!! $route->id !!}</strong></td>
        <td><strong> {!! $route->zone->zone !!}</strong></td>
        <td><strong> {!! $route->route_number !!}</strong></td>
        <td><strong> {!! $route->end_time_am !!}</strong></td>
        <td>{!! $route->end_point_am !!}</td>
        <td>{!! $route->start_time_pm !!}</td>
        <td>{!! $route->start_point_pm !!}</td>
        <td>{!! $route->end_time_pm !!}</td>
        @can('update', $route)
            <td class="hidden-xs" style="width:2%;">
                <a title="Edit"
                   href="{!! URL::route('update_route', $route->id) !!}"
                   class="pull-right"><i class="fa fa-pencil-square-o fa"></i>
                    <a>
            </td>
            <td class="hidden-xs" style="width:2%;">
                <a title="Remove"
                   href="{!! URL::route('remove_route', $route->id) !!}"
                   class="pull-right"><i class="fa fa-times"></i>
                    <a>
            </td>
        @endcan
    </tr>
@endforeach 
mushood's avatar
mushood
Best Answer
Level 41

While the overhead would maybe depend on the the number of routes.

As for the gate check, you can do this:

First extract the common element into another blade.php named ,for example, component/defaultroute.php

/* defaultroute.php */

        <td><strong> {!! $route->id !!}</strong></td>
        <td><strong> {!! $route->zone->zone !!}</strong></td>
        <td><strong> {!! $route->route_number !!}</strong></td>
        <td><strong> {!! $route->end_time_am !!}</strong></td>
        <td>{!! $route->end_point_am !!}</td>
        <td>{!! $route->start_time_pm !!}</td>
        <td>{!! $route->start_point_pm !!}</td>
        <td>{!! $route->end_time_pm !!}</td>

and then in your main blade:

@can('update', $route)
        @include('components.defaultroute')
             <td class="hidden-xs" style="width:2%;">
                <a title="Edit"
                   href="{!! URL::route('update_route', $route->id) !!}"
                   class="pull-right"><i class="fa fa-pencil-square-o fa"></i>
                    <a>
            </td>
            <td class="hidden-xs" style="width:2%;">
                <a title="Remove"
                   href="{!! URL::route('remove_route', $route->id) !!}"
                   class="pull-right"><i class="fa fa-times"></i>
                    <a>
            </td>

@else 
         @include('components.defaultroute')
@endcan

Hope this helps

Snapey's avatar

first i would add debugbar to see if the permissions are being checked for each route. You can then also see the benefit of any refactor.

The only suggestion I can make is to get the ids of all the routes that the user can edit in one separate collection, in one db request and then use a simple has query in the view

kieranjfahy's avatar

Hi, thanks everyone @Snapey I do have the debugger installed, it show's 135 gate requests. I think what @zachleigh says makes perfect sense and this would the requests down by half, but I think what @mushood is showing was what I was looking for and I can put the loop in that.

kieranjfahy's avatar

Just an update, the extract helped and reduced it to 3 gate checks however the views increased to 70. My solution was to have two separate files with the loops inside 'userRoutes' and adminRoutes', the only difference is the admin routes have the remove and edit buttons.

The big problem with doing it this way, I now have to maintain two files rather than one.

Please or to participate in this conversation.