Use Laravel Observers and Global Scopes to Create User Multi-Tenancy

Multi-tenant application are pretty common these days, where database are entries can be accessed only by users who created them. In this article, I will show the simplest way to achieve it in Laravel.

First, I want to admit that there are a lot of ways to implement or even think about multi-tenancy. For more thoughts on this, I recommend a wonderful presentation called Multi-Tenant Laravel by Tom Schlick. In this article, I will show multi-tenancy based on single database and Laravel Global Scopes.

Now, let’s add multi-tenancy to our database entries. Let’s imagine we have DB table called posts, and we want each user to see only their own posts.

Step 1. User’s field in DB table

First, we need to add user’s field into posts table.

Then, we add a foreign key to users table:

Finally, this field should be in model’s fillable array:

Step 2. Fill in user_id automatically

Now, we need to fill it in automatically with currently logged in user, right? For that, we can use Laravel Observers.

Generate observer class:

Inside of it, we add creating() method:

And we register the observer in app/Providers/AppServiceProvider.php:

Step 3. Filter by User: Access only your own posts

Final goal is to allow access only to posts that you created yourself. To do that, we could add something like ->where(‘user_id’, auth()->id()) in all Eloquent queries, but there’s a better way – to use Eloquent Global Scopes.

We create a file app/Scopes/PostUserScope.php:

And we attach it to app/Post.php model by loading in in model’s boot() method:

And that’s it! From now, all the queries for Post model will be filtered by logged in user. So we’ve achieved our goal, to build a basic multi-tenancy system, where every user can create/manage only their own data.

Check out my new online course: Laravel Eloquent: Expert Level

3 thoughts on “Use Laravel Observers and Global Scopes to Create User Multi-Tenancy

  1. Hi Povilas,
    I have been reading your Laraveldaily blog for a while now. I think you guys are doing a great job!
    I have a suggestion: maybe instead of using laravel observers (model events) it makes more sense to use a posts relationship when creating a post, because it reads better.

    auth()->user()->posts()->create([‘body’ => ‘hello world]);

Leave a Reply

Your email address will not be published. Required fields are marked *