Skip to content

Commit dd3ccf5

Browse files
erikn69drbyte
andauthored
Explicitly call loadMissing('permissions') when the relation is needed, and test with Model::preventLazyLoading() (spatie#2776)
* call loadMissing('permissions') when relation is referenced * Test with `Model::preventLazyLoading()` * Model::preventsLazyLoading() check added --------- Co-authored-by: Chris Brown <[email protected]>
1 parent 9895552 commit dd3ccf5

File tree

5 files changed

+75
-2
lines changed

5 files changed

+75
-2
lines changed

src/Models/Role.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ public function hasPermissionTo($permission, ?string $guardName = null): bool
188188
throw GuardDoesNotMatch::create($permission->guard_name, $guardName ? collect([$guardName]) : $this->getGuardNames());
189189
}
190190

191-
return $this->permissions->contains($permission->getKeyName(), $permission->getKey());
191+
return $this->loadMissing('permissions')->permissions
192+
->contains($permission->getKeyName(), $permission->getKey());
192193
}
193194
}

src/Traits/HasPermissions.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,8 @@ public function hasDirectPermission($permission): bool
323323
{
324324
$permission = $this->filterPermission($permission);
325325

326-
return $this->permissions->contains($permission->getKeyName(), $permission->getKey());
326+
return $this->loadMissing('permissions')->permissions
327+
->contains($permission->getKeyName(), $permission->getKey());
327328
}
328329

329330
/**

tests/HasPermissionsTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Spatie\Permission\Tests;
44

5+
use Illuminate\Database\Eloquent\Model;
56
use DB;
67
use Spatie\Permission\Contracts\Permission;
78
use Spatie\Permission\Contracts\Role;
@@ -765,4 +766,37 @@ public function it_can_reject_permission_based_on_logged_in_user_guard()
765766
'status' => false,
766767
]);
767768
}
769+
770+
/** @test */
771+
public function it_can_be_given_a_permission_on_role_when_lazy_loading_is_restricted()
772+
{
773+
$this->assertTrue(Model::preventsLazyLoading());
774+
775+
try {
776+
$testRole = app(Role::class)->with('permissions')->get()->first();
777+
778+
$testRole->givePermissionTo('edit-articles');
779+
780+
$this->assertTrue($testRole->hasPermissionTo('edit-articles'));
781+
} catch (Exception $e) {
782+
$this->fail('Lazy loading detected in the givePermissionTo method: ' . $e->getMessage());
783+
}
784+
}
785+
786+
/** @test */
787+
public function it_can_be_given_a_permission_on_user_when_lazy_loading_is_restricted()
788+
{
789+
$this->assertTrue(Model::preventsLazyLoading());
790+
791+
try {
792+
User::create(['email' => '[email protected]']);
793+
$testUser = User::with('permissions')->get()->first();
794+
795+
$testUser->givePermissionTo('edit-articles');
796+
797+
$this->assertTrue($testUser->hasPermissionTo('edit-articles'));
798+
} catch (Exception $e) {
799+
$this->fail('Lazy loading detected in the givePermissionTo method: ' . $e->getMessage());
800+
}
801+
}
768802
}

tests/HasRolesTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace Spatie\Permission\Tests;
44

5+
use Illuminate\Database\Eloquent\Model;
56
use Illuminate\Support\Facades\DB;
7+
use Spatie\Permission\Contracts\Permission;
68
use Spatie\Permission\Contracts\Role;
79
use Spatie\Permission\Exceptions\GuardDoesNotMatch;
810
use Spatie\Permission\Exceptions\RoleDoesNotExist;
@@ -856,4 +858,37 @@ public function it_does_not_detach_roles_when_user_soft_deleting()
856858

857859
$this->assertTrue($user->hasRole('testRole'));
858860
}
861+
862+
/** @test */
863+
public function it_can_be_given_a_role_on_permission_when_lazy_loading_is_restricted()
864+
{
865+
$this->assertTrue(Model::preventsLazyLoading());
866+
867+
try {
868+
$testPermission = app(Permission::class)->with('roles')->get()->first();
869+
870+
$testPermission->assignRole('testRole');
871+
872+
$this->assertTrue($testPermission->hasRole('testRole'));
873+
} catch (Exception $e) {
874+
$this->fail('Lazy loading detected in the givePermissionTo method: ' . $e->getMessage());
875+
}
876+
}
877+
878+
/** @test */
879+
public function it_can_be_given_a_role_on_user_when_lazy_loading_is_restricted()
880+
{
881+
$this->assertTrue(Model::preventsLazyLoading());
882+
883+
try {
884+
User::create(['email' => '[email protected]']);
885+
$user = User::with('roles')->get()->first();
886+
$user->assignRole('testRole');
887+
888+
$this->assertTrue($user->hasRole('testRole'));
889+
} catch (Exception $e) {
890+
$this->fail('Lazy loading detected in the givePermissionTo method: ' . $e->getMessage());
891+
}
892+
}
893+
859894
}

tests/TestCase.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Spatie\Permission\Tests;
44

5+
use Illuminate\Database\Eloquent\Model;
56
use Illuminate\Database\Schema\Blueprint;
67
use Illuminate\Foundation\Console\AboutCommand;
78
use Illuminate\Http\Request;
@@ -110,6 +111,7 @@ protected function getPackageProviders($app)
110111
*/
111112
protected function getEnvironmentSetUp($app)
112113
{
114+
Model::preventLazyLoading();
113115
$app['config']->set('permission.register_permission_check_method', true);
114116
$app['config']->set('permission.teams', $this->hasTeams);
115117
$app['config']->set('permission.testing', true); // fix sqlite

0 commit comments

Comments
 (0)