The last thing before we start working on the Flutter mobile application is that we want multi-tenancy for our Users. In our case, we want the easiest multi-tenancy option - user_id
filtering. So, let's implement the following:
- Global scopes for Category and Transaction models
- Refactoring of Category and Transaction controllers to create records for our user
These are small changes, but they will make our application multi-tenant. Let's start with the global scope.
Global Scopes for Category and Transaction Models
Let's start with a quick overview of our logic:
- On our Models, we have a
user_id
column that relates to the User - We want to apply a global scope to our Models to filter records by
user_id
- This should be done automatically when we query our Models
Let's implement this in our Category model:
app/Models/Category.php
use Illuminate\Database\Eloquent\Builder; // ... protected static function booted(): void{ if (auth()->check()) { static::addGlobalScope('by_user', function (Builder $builder) { $builder->where('user_id', auth()->id()); }); }}
And we can do exactly the same to our Transaction model:
app/Models/Transaction.php
use Illuminate\Database\Eloquent\Builder; // ... protected static function booted(): void{ if (auth()->check()) { static::addGlobalScope('by_user', function (Builder $builder) { $builder->where('user_id', auth()->id()); }); }}
That's it! Now, if we use our API token and query Categories - we can't see any since we don't have any Categories created for our User:
Modifying Record Creation
Let's fix the problem of our Users not having any Categories or Transactions. We will modify our Category and Transaction controllers to create records for our User:
app/Http/Controllers/CategoryController.php
// ... public function store(StoreCategoryRequest $request){ return new CategoryResource(Category::create($request->validated())); $category = auth()->user()->categories()->create($request->validated()); return new CategoryResource($category);}
We simply switch from Category::create
to auth()->user()->categories()->create()
. But for this to work, we have to add the relationship to our User model:
app/Models/User.php
use Illuminate\Database\Eloquent\Relations\HasMany; // ... public function categories(): HasMany{ return $this->hasMany(Category::class);}
And we can do the same for our Transaction controller:
app/Http/Controllers/TransactionController.php
public function store(StoreTransactionRequest $request){ return new TransactionResource(Transaction::create($request->validated())); $transaction = auth()->user()->transactions()->create($request->validated()); return new TransactionResource($transaction);}
And once again, we have to add the relationship to our User model:
app/Models/User.php
// ... public function categories(): HasMany{ return $this->hasMany(Category::class);} public function transactions(): HasMany{ return $this->hasMany(Transaction::class);}
Now, let's try to create a Category using Postman:
And, of course, if we try to load all categories, we see only the one we created:
That's it. We have implemented a simple multi-tenancy for our Users.
In the next lesson, we will start working on the Flutter application. We will start with a basic setup and get to know the Flutter environment.
Check out the GitHub Commit
No comments yet…