eta-orionis's avatar

Seeding models that are forced-associated with auth()->user()

In order to force models to belong to a user (so I can apply global scopes for multitenancy), I have the following in my model:

        static::creating(function (Item $item) {
            $item->user()->associate(auth()->user());
        });

In my seeder I have

$user=User::factory()->create();
  Item::factory()->for($user)->create();

However, this forces the user to null, due to auth()->user() in static::creating being null during artisan db:seed. How can I seed while not compromising the security of the solution?

0 likes
1 reply
LaryAI's avatar
Level 58

One solution could be to pass the user ID as a parameter to the seeder and use it to associate the item with the user. This way, you can still apply the global scope for multitenancy while seeding the database. Here's an example:

In your seeder:

$user = User::factory()->create();
Item::factory()->forUser($user->id)->create();

In your Item model:

static::creating(function (Item $item) {
    if (auth()->check()) {
        $item->user()->associate(auth()->user());
    } elseif ($item->user_id) {
        $item->user()->associate(User::find($item->user_id));
    }
});

public function scopeForUser($query, $userId)
{
    return $query->where('user_id', $userId);
}

This way, if the user is authenticated, the item will be associated with the authenticated user. If not, it will be associated with the user ID passed to the forUser scope.

Please or to participate in this conversation.