Back to Course |
Laravel 11 Multi-Tenancy: All You Need To Know

Create Tenant at Registration

Now, we take the scenario of team multi-tenancy or company multi-tenancy, which means that every record should belong to a tenant, which will have many users inside.

So every user will have access to their team's records. There are multiple ways how you can implement all of that.

Generally, whether you use some package or not, you need to implement these things with multi-tenancy:

  1. Creating the tenant and assigning a user to the tenant. We will take the case of many-to-many relationships when a user may belong to multiple tenants.
  2. Switching between the tenants.
  3. Identify the tenant, which may be done by subdomain, session, or in other ways.
  4. Finally, the records should be limited by team: for example, with global scopes.
  5. As a bonus, you should probably have some invitation system to add more users to your team and tenant.

First, in this section of the course, we will implement it without any packages, only by manually creating the features above. So you would understand the logic of how it works.

In the following sections, we will perform the same or very similar features with packages. You will be able to compare and choose which package you like the most, or you will like implementing everything without any packages.


In this lesson, let's create the team or the tenant during registration. We have a default registration from Laravel Breeze, and after registration, we will create a tenant for a user.

First, let's create a tenant Model. The tenant will only have a name.

php artisan make:model Tenant -m

database/migrations/xxx_create_tenants_table.php:

Schema::create('tenants', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});

app/Models/Tenant.php:

class Tenant extends Model
{
protected $fillable = ['name'];
}

Also, we need a pivot table for a many-to-many relationship between users and tenants tables.

php artisan make:migration "create tenant user table"

database/migrations/xxx_create_tenant_user_table.php:

Schema::create('tenant_user', function (Blueprint $table) {
$table->foreignId('tenant_id')->constrained();
$table->foreignId('user_id')->constrained();
});

Next, in the Tenant Model, let's add the relationship to the User Model.

app/Models/Tenant.php:

use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
class Tenant extends Model
{
protected $fillable = ['name'];
 
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class);
}
}

Now, we can create the tenant when the user registers. In Breeze, the login for registration is in the RegisteredUserController Controller. We will name the tenant by the user's name and add a Team suffix. When the tenant is created, we must attach it to a user.

app/Http/Controllers/Auth/RegisteredUserController.php:

use App\Models\Tenant;
 
class RegisteredUserController extends Controller
{
// ...
 
public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
 
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
 
$tenant = Tenant::create(['name' => $request->name . ' Team']);
$tenant->users()->attach($user);
 
event(new Registered($user));
 
Auth::login($user);
 
return redirect(route('dashboard', absolute: false));
}
}

After registering in the database, we see that the tenant has been created and attached to the user.


In the next lesson, we will limit the tasks and projects to that tenant.