Home About Projects Skills Writing Contact
← All writing
Jun 16, 2025 3 min read · Laravel· PHP· Multi-tenancy· Tooling

Fixing Laravel IDE Helper for Multi-Tenant Setups with Stancl Tenancy

Fixing Laravel IDE Helper for Multi-Tenant Setups with Stancl Tenancy

While Laravel IDE Helper works great for standard applications, things break down in multi-tenant apps — especially when tenant databases differ from the landlord. Here's how I got it working with Stancl Tenancy.

I have used Barry's Laravel IDE Helper in a lot of my projects. PHPStorm's Laravel Idea plugin is also excellent, but for those who don't want a paid option, IDE Helper is the go-to. What I particularly like is how it adds database column names as PHPDoc properties on Eloquent model classes — which eliminates a significant class of errors that PHPStan/Larastan would otherwise flag.

It worked great until I needed it in a multi-database multi-tenant application with a landlord database and multiple tenant databases (using stancl/tenancy). The way this package works:

  • The landlord database is set in .env as the main connection
  • When a request comes in, the package reads the domain from the landlord database, identifies the tenant, and switches context to the tenant's database

The problem

When I ran php artisan ide-helper:models -W, the column annotations in my Eloquent models were wrong. After some investigation, I realised IDE Helper was reading from the landlord database — which doesn't contain the tenant tables. The actual model fields live in the tenant databases, but since tenancy was never initialised during the command, IDE Helper never saw them.

I looked through the IDE Helper configuration but found nothing to point it at a different connection per model. So I wrote a workaround.

The fix: a custom Artisan command

<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Models\Tenant;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;

class GenerateTenantIDEHelper extends Command
{
    protected $signature = 'tenancy:ide-helper';

    protected $description = 'Generate IDE Helper annotations using a tenant database connection';

    public function handle(): void
    {
        $tenant = Tenant::first();

        if (! $tenant) {
            $this->info('No tenants found. Exiting.');
            return;
        }

        $this->info('Initialising tenant context for IDE Helper generation...');

        tenancy()->initialize($tenant);

        Artisan::call('ide-helper:generate');
        Artisan::call('ide-helper:meta');
        Artisan::call('ide-helper:models', ['-W' => true]);

        tenancy()->end();

        $this->info('IDE Helper generation completed.');
    }
}

Run it with:

php artisan tenancy:ide-helper

The logic is straightforward:

  1. Find any available tenant — it doesn't matter which one, they all share the same schema
  2. Initialise tenancy with that tenant, switching the active connection to the tenant database
  3. Run the three IDE Helper commands — they now read from the tenant database and see all the actual columns
  4. End tenancy, restoring the landlord connection

What each command does

ide-helper:generate

Generates _ide_helper.php with autocomplete stubs for Laravel facades, helpers, and macros. Helps your IDE understand dynamic magic methods.

ide-helper:meta

Generates .phpstorm.meta.php, which helps PHPStorm understand service container bindings and app()->make() calls — useful when working with dependency injection.

ide-helper:models -W

Scans your Eloquent models and writes their database columns directly into the class files as @property PHPDoc annotations. The -W flag writes to the files rather than generating a separate helper file. This is the one that fixes PHPStan complaints about unknown model properties.


The full command is available as a Gist on GitHub.

TL;DR: If Laravel IDE Helper is pulling fields from the wrong database in your multi-tenant project, initialise a known tenant before running the ide-helper commands. One custom command, and your model annotations will reflect your actual tenant schema.

Bright Nkrumah
Senior software engineer in Kumasi, Ghana. Twelve years of writing PHP, and counting.
More writing