Skip to content

Commit b881a07

Browse files
Fix Role::withCount if belongsToMany declared (#2280)
* Fix Role::withCount if belongsToMany declared fixes #2277
1 parent 3859d92 commit b881a07

File tree

4 files changed

+170
-5
lines changed

4 files changed

+170
-5
lines changed

src/Models/Role.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,7 @@ public function __construct(array $attributes = [])
3434
parent::__construct($attributes);
3535

3636
$this->guarded[] = $this->primaryKey;
37-
}
38-
39-
public function getTable()
40-
{
41-
return config('permission.table_names.roles', parent::getTable());
37+
$this->table = config('permission.table_names.roles', parent::getTable());
4238
}
4339

4440
public static function create(array $attributes = [])

tests/RoleWithNesting.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace Spatie\Permission\Test;
4+
5+
use Illuminate\Database\Eloquent\Collection;
6+
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
7+
8+
/**
9+
* @property Collection $parents
10+
* @property Collection $children
11+
*/
12+
class RoleWithNesting extends \Spatie\Permission\Models\Role
13+
{
14+
const HIERARCHY_TABLE = 'roles_hierarchy';
15+
16+
/**
17+
* @return BelongsToMany
18+
*/
19+
public function parents()
20+
{
21+
return $this->belongsToMany(
22+
static::class,
23+
static::HIERARCHY_TABLE,
24+
'child_id',
25+
'parent_id');
26+
}
27+
28+
/**
29+
* @return BelongsToMany
30+
*/
31+
public function children(): BelongsToMany
32+
{
33+
return $this->belongsToMany(
34+
static::class,
35+
static::HIERARCHY_TABLE,
36+
'parent_id',
37+
'child_id');
38+
}
39+
}

tests/RoleWithNestingTest.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
namespace Spatie\Permission\Test;
4+
5+
class RoleWithNestingTest extends TestCase
6+
{
7+
private static $old_migration;
8+
/**
9+
* @var RoleWithNesting[]
10+
*/
11+
protected $parent_roles=[];
12+
/**
13+
* @var RoleWithNesting[]
14+
*/
15+
protected $child_roles=[];
16+
17+
public static function setUpBeforeClass(): void
18+
{
19+
parent::setUpBeforeClass();
20+
self::$old_migration = self::$migration;
21+
self::$migration = self::getMigration();
22+
}
23+
24+
public function setUp(): void
25+
{
26+
parent::setUp();
27+
$this->parent_roles = [];
28+
$this->child_roles = [];
29+
$this->parent_roles["has_no_children"] = RoleWithNesting::create(["name"=>"has_no_children"]);
30+
$this->parent_roles["has_1_child"] = RoleWithNesting::create(["name"=>"has_1_child"]);
31+
$this->parent_roles["has_3_children"] = RoleWithNesting::create(["name"=>"has_3_children"]);
32+
33+
$this->child_roles["has_no_parents"] = RoleWithNesting::create(["name"=>"has_no_parents"]);
34+
$this->child_roles["has_1_parent"] = RoleWithNesting::create(["name"=>"has_1_parent"]);
35+
$this->child_roles["has_2_parents"] = RoleWithNesting::create(["name"=>"has_2_parents"]);
36+
$this->child_roles["third_child"] = RoleWithNesting::create(["name"=>"third_child"]);
37+
38+
$this->parent_roles["has_1_child"]->children()->attach($this->child_roles["has_2_parents"]);
39+
$this->parent_roles["has_3_children"]->children()->attach($this->child_roles["has_2_parents"]);
40+
$this->parent_roles["has_3_children"]->children()->attach($this->child_roles["has_1_parent"]);
41+
$this->parent_roles["has_3_children"]->children()->attach($this->child_roles["third_child"]);
42+
}
43+
44+
public static function tearDownAfterClass(): void
45+
{
46+
parent::tearDownAfterClass();
47+
self::$migration = self::$old_migration;
48+
}
49+
50+
protected function getEnvironmentSetUp($app)
51+
{
52+
parent::getEnvironmentSetUp($app);
53+
$app['config']->set('permission.models.role', RoleWithNesting::class);
54+
$app['config']->set('permission.table_names.roles', "nesting_role");
55+
}
56+
57+
protected static function getMigration()
58+
{
59+
require_once __DIR__."/customMigrations/roles_with_nesting_migration.php.stub";
60+
return new \CreatePermissionTablesWithNested();
61+
}
62+
63+
/** @test
64+
* @dataProvider roles_list
65+
*/
66+
public function it_returns_correct_withCount_of_nested_roles($role_group,$index,$relation,$expectedCount)
67+
{
68+
$role = $this->$role_group[$index];
69+
$count_field_name = sprintf("%s_count", $relation);
70+
71+
$actualCount = intval(RoleWithNesting::query()->withCount($relation)->find($role->id)->$count_field_name);
72+
73+
$this->assertSame(
74+
$expectedCount,
75+
$actualCount,
76+
sprintf("%s expects %d %s, %d found",$role->name,$expectedCount,$relation,$actualCount)
77+
);
78+
}
79+
80+
public function roles_list(){
81+
return [
82+
["parent_roles","has_no_children","children",0],
83+
["parent_roles","has_1_child","children",1],
84+
["parent_roles","has_3_children","children",3],
85+
["child_roles","has_no_parents","parents",0],
86+
["child_roles","has_1_parent","parents",1],
87+
["child_roles","has_2_parents","parents",2],
88+
];
89+
}
90+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\Schema;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Database\Migrations\Migration;
6+
use Spatie\Permission\PermissionRegistrar;
7+
8+
require_once __DIR__."/../../database/migrations/create_permission_tables.php.stub";
9+
class CreatePermissionTablesWithNested extends CreatePermissionTables
10+
{
11+
/**
12+
* Run the migrations.
13+
*
14+
* @return void
15+
*/
16+
public function up()
17+
{
18+
parent::up();
19+
$tableNames = config('permission.table_names');
20+
21+
Schema::create(\Spatie\Permission\Test\RoleWithNesting::HIERARCHY_TABLE,function(Blueprint $table) use ($tableNames){
22+
$table->id();
23+
$table->bigInteger("parent_id", false, true);
24+
$table->bigInteger("child_id", false, true);
25+
$table->foreign("parent_id")->references("id")->on($tableNames['roles']);
26+
$table->foreign("child_id")->references("id")->on($tableNames['roles']);
27+
});
28+
}
29+
30+
/**
31+
* Reverse the migrations.
32+
*
33+
* @return void
34+
*/
35+
public function down()
36+
{
37+
parent::down();
38+
Schema::drop(\Spatie\Permission\Test\RoleWithNesting::HIERARCHY_TABLE);
39+
}
40+
}

0 commit comments

Comments
 (0)