Hi LaraPeeps !
I am trying to figure out how to update the role column in team_user to a json column "roles" so a user can have many roles.
My schema looks like this:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('team_user', function (Blueprint $table) {
$table->id();
$table->foreignId('team_id');
$table->foreignId('user_id');
$table->json('roles')->nullable();
$table->timestamps();
$table->unique(['team_id', 'user_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('team_user');
}
};
Anyway long and the short of it all my tests pass except 2
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class UpdateTeamMemberRoleTest extends TestCase
{
use RefreshDatabase;
public function test_team_member_roles_can_be_updated(): void
{
$this->actingAs($user = User::factory()->withPersonalTeam()->create());
// Attach another user with the initial "admin" role
$user->currentTeam->users()->attach(
$otherUser = User::factory()->create(), ['roles' => json_encode(['admin'])]
);
// Update the role of the attached user
$this->put('/teams/' . $user->currentTeam->id . '/members/' . $otherUser->id, [
'roles' => json_encode(['editor']),
]);
// Reload team and user to ensure the latest data is retrieved
$updatedRoles = $user->currentTeam->users()->find($otherUser->id)->pivot->roles;
$this->assertEquals(['editor'], json_decode($updatedRoles, true));
}
public function test_only_team_owner_can_update_team_member_roles(): void
{
$user = User::factory()->withPersonalTeam()->create();
// Attach another user with the initial "admin" role
$user->currentTeam->users()->attach(
$otherUser = User::factory()->create(), ['roles' => json_encode(['admin'])]
);
// Act as the other user, attempting to update their own role
$this->actingAs($otherUser);
$response = $this->put('/teams/' . $user->currentTeam->id . '/members/' . $otherUser->id, [
'roles' => json_encode(['editor']),
]);
// Verify the request was unauthorized
$response->assertStatus(403);
// Ensure roles remain unchanged
$unchangedRoles = $user->currentTeam->users()->find($otherUser->id)->pivot->roles;
$this->assertEquals(['admin'], json_decode($unchangedRoles, true));
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('team_user', function (Blueprint $table) {
$table->id();
$table->foreignId('team_id');
$table->foreignId('user_id');
$table->json('roles')->nullable();
$table->timestamps();
$table->unique(['team_id', 'user_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('team_user');
}
};
in the Team model I have the following method:
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class, 'team_user')
->withPivot('roles') // Reference the roles column
->withTimestamps();
}
I assume I need override jetstreams controller somehow but since laravel 11 these seem to be somewhere in the vendor files but I am sure they can be extended in some way I just don't know how?