Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

haao98's avatar

How to seed with two foreign keys?

Hey I am very new to Laravel 9 so I am a total beginner. My question is how can I seed a migration with two different foreign keys. So I have three database tables users, plants and rooms. The rooms table has an user_id column to reference the user. Now the problem is in the plants column. My plants column has an user_id and a room_id. When I seed the user I wrote this code:

    public function run()
    {
        User::factory()
            ->count(50)
            ->hasRooms(2)
            ->hasPlants(5)
            ->create();
    }
// https://laravel.com/docs/9.x/database-testing#has-many-relationships

This code fills the users table and the rooms table, because my user model has the hasMany() method.

class User extends Model
{
    use HasFactory;

    public function plants()
    {
        return $this->hasMany(Plant::class);
    }

    public function rooms()
    {
        return $this->hasMany(Room::class);
    }
}

Now my problem is that the room_id column from plants table is still empty but the rest is filled. How can i seed the one empty room_id column using the existing tables. Because I can't only seed the room_id without creating new data, but as mentioned before, I would like to use the existing data from the User seed.

Here are some other code snippets which may be relevant:

Relationship:

class Room extends Model
{
    use HasFactory;

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function plants()
    {
        return $this->hasMany(Plant::class);
    }
}
class Plant extends Model
{
    use HasFactory;

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function room()
    {
        return $this->belongsTo(Room::class);
    }
}

Migration:

//Plants migration
    public function up()
    {
        Schema::create('plants', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->text('description')->nullable();
            $table->date('last_time_watered')->nullable();
            $table->integer('days_to_water')->nullable();
            $table->foreignId('user_id')->constrained();
            $table->foreignId('room_id')->constrained();
            $table->timestamps();
        });
    }
//Rooms migration
    public function up()
    {
        Schema::create('rooms', function (Blueprint $table) {
            $table->id();
            $table->string('room_name', 255);
            $table->foreignId('user_id')->constrained();
            $table->timestamps();
        });
    }
//Users migration
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('first_name');
            $table->string('last_name');
            $table->string('password');
            $table->string('email');
            $table->timestamps();
        });
    }

I hope my question is somehow understandable and thanks in advance. :)

0 likes
2 replies
vincent15000's avatar

I have not directly the answer, I wonder if I have not yet had the same problem.

I do this that way, perhaps you will see any possibility for you.

public function run()
{
    $roles = Role::all();
    $authors = Author::all();
    $publishers = Publisher::all();
    Game::factory()
        ->count(50)
        ->create()
        ->each(function($game) use ($roles, $authors, $publishers) {
            foreach ($roles as $role) {
                $authorsIds = $authors->random(random_int(1, 2))->pluck('id');
                $game->authors()->attach($authorsIds, ['role_id' => $role->id]);
            }
            $publishersIds = $publishers->random(random_int(1, 2))->pluck('id');
            $game->publishers()->attach($publishersIds);
        });
}

Tell me if it helps.

1 like

Please or to participate in this conversation.