DEV Community

Cover image for How to easily generate data with Database Seeders in Laravel
Adetola
Adetola

Posted on • Updated on

How to easily generate data with Database Seeders in Laravel

When building an application, be it small, medium, or large. Having test data to play around with in an application is inevitable and important.

So let's start from simple to advanced with two different scenarios.

i. All applications or the majority of applications should have users. Sometimes, we want to classify/tag users as Admin or regular Users. So let's generate a simple seeder with 100 users with the under-listed table specifications:

  • ID, First Name, Last Name, Email, Password
  • User Type: Either an Admin or a regular User

So here we go.

To seed into the users table, of course, you would have the default users migration table created for you by Laravel.

So for the sake of this demonstration, your table migration should look like this:

public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('first_name');
            $table->string('last_name');
            $table->string('email');
            $table->string('password');
            $table->enum('user_type', ['user','admin'])->default('user');
            $table->rememberToken();
            $table->timestamps();
        });
    }
Enter fullscreen mode Exit fullscreen mode

To create a seeder class for our Users Table.

php artisan make:seeder UserSeeder
Enter fullscreen mode Exit fullscreen mode

So, to create values for the seeder we just created we need to use the default Faker package that comes with every Laravel application.

To generate 100 users at a go, we first do a for-loop and pass the fake/pseudo data into each column like this:

use Faker\Factory as Faker;

public function run()
{
   $faker = Faker::create();

   for(i = 0; i <= 99; i++)
   {
      User::create([
        'first_name' => $faker->firstName(),
        'last_name' => $faker->lastName(),
        'email' => $faker->email(),
        'password' => bcrypt('hello1234'), // we might want to set this to a value we can easily remember for testing sake
        'user_type' => $faker->randomElement(['admin', 'user'])
      ]);
   }
}
Enter fullscreen mode Exit fullscreen mode

To seed this into the database, we need to run the command below:

php artisan db:seed --class=UserSeeder
Enter fullscreen mode Exit fullscreen mode

This will create 100 users and insert them into the database.

It is that simple.

So now, to a more advanced solution.

We need to create:

  • A departments table with 10 new departments.
  • We will create new 100 users.
  • A staff table that will reference the users table with the same details and an extra column to reference the departments table i.e department_id.

We already know what the users table will look like let's look at what the staff and department tables will look like.

Staff table

Schema::create('staff', function (Blueprint $table) {
            $table->id();
            $table->string('first_name');
            $table->string('last_name');
            $table->string('email');
            $table->foreignId('department_id')->references('id')->on('departments');
            $table->foreignId('user_id')->references('id')->on('users');
            $table->timestamps();
        });
Enter fullscreen mode Exit fullscreen mode

Departments table:

Schema::create('departments', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
Enter fullscreen mode Exit fullscreen mode

So we need to run migration to have these tables in our database.

Now, for the UserSeeder class, we are to implement the bullet points stated earlier.

  • A department table with 10 new departments.
$now = now();
        $count = 0;
        $departmentNames = ['Human Resources', 'Admin', 'ICT', 'Customer Service', 'Operations', 'Branding','Legal',
            'Risk', 'Audit', 'Finance', 'Infrastructure'
        ];

        for ($j=0; $j <= 9; $j++){
            Department::create([
                'name' => $departmentNames[$j],
                'created_at' => $now,
                'updated_at' => $now,
            ]);
            $count++;
        }
Enter fullscreen mode Exit fullscreen mode

The last two bullet points will need to be implemented together

  • We will create new 100 users
  • A staff table that will reference the users table with the same details and an extra column to reference the departments table i.e department_id.
if ($count == 10) { // we need to make sure we have all 10 departments
            $departments = Department::pluck('id')->toArray();

            for ($i=0; $i <= 99; $i++) {
                $user = User::create([
                    'first_name' => $faker->firstName(),
                    'last_name' => $faker->lastName(),
                    'email' => $faker->email(),
                    'password' => bcrypt('hello1234'),
                    'user_type' => $faker->randomElement(['admin', 'user']),
                    'created_at' => $now,
                    'updated_at' => $now
                ]);

                Staff::create([
                    'first_name' => $user->first_name,
                    'last_name' => $user->last_name,
                    'email' => $user->email,
                    'user_id' => $user->id,
                    'department_id' => $faker->randomElement($departments), // pick random departments from DB
                    'created_at' => $now,
                    'updated_at' => $now
                ]);
            }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • We created 10 departments first.

  • Then we set up a counter to check if all 10 departments have been created.

  • If the counter condition is true, we then create 100 users.

  • For each of these 100 users, we need to reference their details in another table called staffs table.

  • Each staff must belong to a user and must also belong to a department, so to do this, we need to get all the departments we created earlier and inject them into the department_id column randomly.

The full UserSeeder implementation

        $now = now();
        $count = 0;
        $departmentNames = ['Electronics', 'Home & Garden', 'Toys & Games', 'Health & Beauty', 'Automotive', 'Sports & Outdoors','Clothing & Accessories',
            'Books', 'Music', 'Movies & TV', 'Grocery'
        ];

        for ($j=0; $j <= 9; $j++){
            Department::create([
                'name' => $departmentNames[$j],
                'created_at' => $now,
                'updated_at' => $now,
            ]);
            $count++;
        }

        $faker = Faker::create();
        if ($count == 10) {
            $departments = Department::pluck('id')->toArray();

            for ($i=0; $i <= 99; $i++) {
                $user = User::create([
                    'first_name' => $faker->firstName(),
                    'last_name' => $faker->lastName(),
                    'email' => $faker->email(),
                    'password' => bcrypt('hello1234'),
                    'user_type' => $faker->randomElement(['admin', 'user']),
                    'created_at' => $now,
                    'updated_at' => $now
                ]);

                Staff::create([
                    'first_name' => $user->first_name,
                    'last_name' => $user->last_name,
                    'email' => $user->email,
                    'user_id' => $user->id,
                    'department_id' => $faker->randomElement($departments), // pick random departments from DB
                    'created_at' => $now,
                    'updated_at' => $now
                ]);
            }
        }
Enter fullscreen mode Exit fullscreen mode

Then run:

php artisan make:seeder --class=UserSeeder
Enter fullscreen mode Exit fullscreen mode

If you have questions, do not hesitate to drop it. Happy coding!

Top comments (0)