Laravel 8 — Class Based Factories is Amazing.
Hi friends,
Already a while before Laravel 8 version introduced. This major version contain many new and great stuffs for making Laravel more strong.
You can see all updates of Laravel 8 via this link. On this post we shell discuss just one of the new features— Class Based Factories.
The main reason of my writing about this functions is — Already Laravel 8 introduced a while some friends have trouble for making relationship between factories and they surprised by seeing new code styles of factory classes due to architectural changes (many people even dont know about Laravel 8 changed factory’s main working idea although Laravel note this detailed on its documentation as all features of it as habit).
For not losing time I will add some examples both old school style and new school style. Look at my example:
Assume you have two factories for User and Task models regarding to UserFactory and TaskFactory
Note : there are hasMany relationships between User and Task models on my example.
Before class based factories launced assume you would like to make User and Task factories then you should create codes such :
User Factory :
<?php
…
…
$factory->define(User::class, function (Faker $faker) {
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];;});
TaskFactory :
<?php
…
…
$factory->define(Task::class, function (Faker $faker) {
return [
‘description’=>$this->faker->text,
‘deadline’=>$this->faker->dateTimeBetween(‘now’,’+1 years’)
];;});
DatabaseSeeder.php
….
public function run() {
factory(\App\Models\User::class,6)
->create()
->each(function ($user)
{
factory(\App\Models\Task::class,6)
->make()
->each(function ($task) use ($user)
{ $user
->task()
->save($user); //define hasMany relationship
});
});
}
….
This looking is bored , not good and clearified.
But Class based factories offer us more comfortable way to done this task.
class based factories giving as a good architecture which we can define our factory model in a protected valuable and defining body of factory within class’s function , for example :
protected $model = Task::class;public function definition()
{
return [
'description'=>$this->faker->text,
'deadline'=>$this->faker->dateTimeBetween('now','+10 years')
];
}
Now we define our model based factories:
TaskFactory
<?php
namespace Database\Factories;
use App\Models\Task;
use Illuminate\Database\Eloquent\Factories\Factory;
class TaskFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Task::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'description'=>$this->faker->text,
'deadline'=>$this->faker->dateTimeBetween('now','+30 years')
];
}
}
UserFactory
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = User::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
}
Call it in everywhere you want just one line with more simple code!
User::factory(10)
->has(Task::factory()
->count(5))
->create();
As you can see , Laravel Class Factories offer this amazing way, I really loved it , it will reduce a lot time while writing factories, it will be more readible. If you still not use class based factories try it and make your codes great!.