When working with Filament and having models that need to be restricted by a company scope, correctly assigning the company_id in records can be challenging, especially when handling bulk imports. In this article, I will share my experience and solution to this problem.
In my system, I manage two main models:
Although I do not use Filament's multi-tenancy system, all my queries are restricted by a scope to ensure that each user only sees records belonging to their company.
Initially, I tried assigning the company_id to the worker in the WorkerObserver. To do this, I retrieved the company ID from the authenticated user using auth()->user()->company_id and assigned it in the creating event.
However, when performing imports, the process runs inside a Job, which prevents direct access to auth()->user(). I tried using lifehooks and the $import->user() property within the importer, but I couldn’t get it to work properly.
To resolve this issue, I modified the import action in WorkerResource, adding a custom option to pass the authenticated user's company_id:
->headerActions([ ImportAction::make() ->importer(WorkerImporter::class) ->options(['companyId' => auth()->user()->company_id]) ->maxRows(10000) ])
Then, inside the WorkerImporter, I used the beforeFill() lifehook to assign the company_id if it was not already set:
protected function beforeFill(): void { if (!isset($this->data['company_id'])) { $this->data['company_id'] = $this->options['companyId']; } }
Finally, in my WorkerObserver, I ensured that any manual record creation also assigns the company_id correctly:
public function creating(Worker $worker): void { if (is_null($worker->company_id)) { $worker->company_id = auth()->user()->company_id ?? null; } }
This allowed me to handle both imports and manual insertions or local seeders without issues.
If you're facing similar issues with imports in Filament, this strategy can help ensure that records are correctly assigned to the user's company.
Page loaded in 25.70 ms