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.
Post Contents
# 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 🙂