Laravel Factory For Database Seeding

0
2013
Laravel Factory For Database Seeding

Laravel factory is today’s leading topic. In this tutorial, you’ll learn to seed dummy data using a faker composer package.

Generally, every application requires data for testing. With this intention, Laravel provides model factories along with seeders. As a result, You can create as much dummy data as you want. Furthermore, You can use Laravel eloquent relationships to seed complex foreign key database tables too. You can check the official documents here.

It’s a good habit to create a factory or seeder for every database table. It may take some time to create factories first. But as soon as your functionality raises in the application, it’ll save you lots of valuable time. Moreover, it serves real looking dummy data to test with.

# Requirements

In the first place, install a laravel framework with the following commands. It allows you to access the development server at http://localhost:8000

composer create-project laravel/laravel model-factory
cd model-factory
php artisan serve

# Prerequisite

In this case, I’ll use the Article and Comment models along with the User model. Also, the User model will connect to the Article model with hasMany relationship. In the same way, the Article model will connect to Comment model with hasMany relationship.

Now, let’s create model factories. Laravel already provides UserFactory. But we will create new factories for this tutorial. Seeding a single model is easy, but we’ll seed nested tables with foreign keys. Using the following command will create a factory class in the database > factories directory. You can assign a specific model to the factory too.

php artisan make:factory <factory-name>

php artisan make:factory <factory-name> --model=<model-name>

Besides, there is a shortcut trick while creating a model. You can also create a factory, seeder, and controller with a model. As you can see, laravel comes with a User model, migration, and factory. Same as the User model, we need an Article model and a Comment model. To create both models, migrations, and factories use the following commands:

php artisan make:model Article -mf
php artisan make:model Comment -mf

In the above command, m stands for migration and f stands for factory. Also, you can create a seeder with passing s and a controller with c. But, we don’t need that in this article. We will use the default DatabaseSeeder for further process.

# Creating Schemas

After creating migrations, let’s create a simple schema for Article and Comment tables. We’ll use User table schema as it is. To do that:

/* database > migrations > *_create_articles_table.php */

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
            $table->string('title');
            $table->text('description');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('articles');
    }
}
/* database > migrations > *_create_comments_table.php */

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCommentsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('article_id');
            $table->foreign('article_id')->references('id')->on('articles');
            $table->string('title', 255);
            $table->text('content');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('comments');
    }
}

Next, let’s migrate it with the following command:

php artisan migrate

# Creating Relationships

As you can see, the users table has been connected to the articles table with user_id. Similarly, the articles table has been connected to the comments table with article_id. With this in mind, let’s create a hasMany relationship between User to Article and Article to Comment models.

At the first, into the User model create an articles() function with hasMany relationship.

/*  app > Models > User.php */

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    public function articles() {
        return $this->hasMany('App\Models\Article');
    }

}

In the middle, into the Article model, create a user() function to connect it with User. Also, create comments() function with hasMany relationship. It will connect the Article model to the Comment model.</p

/*  app > Models > Article.php */

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    use HasFactory;

    public function user() {
        return $this->belongsTo('App\Models\User');
    }

    public function comments() {
        return $this->hasMany('App\Models\Comment');
    }
}

Finally, into the Comment model, create user() function for connecting it to the Article model.

/*  app > Models > Comment.php */

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    use HasFactory;

    public function user() {
        return $this->belongsTo('App\Models\User');
    }
}

Creating Factories

At this instant, let’s assign dummy data into the Article and Comment factories. You can use faker instance using $this->faker in factories directly. You can use lots of functions with $this->faker. You can check all documentation here.

/* database > factories > ArticleFactory.php */

<?php

namespace Database\Factories;

use App\Models\Article;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

class ArticleFactory extends Factory
{
    protected $model = Article::class;

    public function definition()
    {
        return [
            'title' => $this->faker->sentence,
            'description' => $this->faker->paragraph
        ];
    }
}
/* database > factories > CommentFactory.php */

<?php

namespace Database\Factories;

use App\Models\Comment;
use App\Models\Article;
use Illuminate\Database\Eloquent\Factories\Factory;

class CommentFactory extends Factory
{
    protected $model = Comment::class;

    public function definition()
    {
        return [
            'title' => $this->faker->word,
            'content' => $this->faker->paragraph
        ];
    }
}

# Seeding Factories

In the end, open the DatabaseSeeder.php and choose the following ways to seed.

# Seeding Single Factory

To seed a simple and single UserFactory you can use it as below.

/* database > seeders > DatabaseSeeder.php */ 

<?php

namespace Database\Seeders;

use App\Models\Comment;
use App\Models\Article;
use App\Models\User;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        User::factory(10)->create();        
    }
}

Seeding Factories With hasMany Relationship

Next, to assign a user with articles you can use hasMany relationship in the factory. It will seed 10 users. Every user will have 5 articles.

/* database > seeders > DatabaseSeeder.php */ 

<?php

namespace Database\Seeders;

use App\Models\Comment;
use App\Models\Article;
use App\Models\User;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
         User::factory(10)
            ->has(Article::factory()->count(5), 'articles') // hasMany relation ship name
            ->create();
    }
}

Seeding Factories With Complex Structured Tables

After that, you can use the above functionality to the next level. This will create 10 comments on every article.

/* database > seeders > DatabaseSeeder.php */ 

<?php

namespace Database\Seeders;

use App\Models\Comment;
use App\Models\Article;
use App\Models\User;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
         User::factory(10)
            ->has(
                Article::factory()->has(
                    Comment::factory()->count(10), 'comments')
                ->count(5), 'articles')
            ->create();
    }
}

Seeding Database

After generating seeding, you can seed the whole database with the following command:

php artisan db:seed
// OR you can regenerate database using
php artisan migrate:refresh --seed

That’s all for the Laravel factory. I hope you like this tutorial. Please share with commenting and share. Happy coding 🙂

Learn more about Laravel Framework

Previous articleFirebase Push Notification Using Laravel
Next articleLaravel Collections To Manipulate Arrays
Welcome to the world of web development, where technology and creativity come together to bring ideas to life. My name is Keyur Gadher, and as a web development blogger, I am here to share my knowledge and experience with you. From front-end web development to back-end programming, I will provide you with valuable tips, tricks, and techniques to help you create beautiful and functional websites that are tailored to your specific needs. Whether you're a beginner or a seasoned pro, I am here to help you take your web development skills to the next level. Join me today and let's start coding!

LEAVE A REPLY

Please enter your comment!
Please enter your name here