1398 lines
32 KiB
Markdown
1398 lines
32 KiB
Markdown
# Eloquent: Factories
|
||
|
||
* Introduction
|
||
* Defining Model Factories
|
||
* Generating Factories
|
||
* Factory States
|
||
* Factory Callbacks
|
||
* Creating Models Using Factories
|
||
* Instantiating Models
|
||
* Persisting Models
|
||
* Sequences
|
||
* Factory Relationships
|
||
* Has Many Relationships
|
||
* Belongs To Relationships
|
||
* Many to Many Relationships
|
||
* Polymorphic Relationships
|
||
* Defining Relationships Within Factories
|
||
* Recycling an Existing Model for Relationships
|
||
|
||
## Introduction
|
||
|
||
When testing your application or seeding your database, you may need to insert
|
||
a few records into your database. Instead of manually specifying the value of
|
||
each column, Laravel allows you to define a set of default attributes for each
|
||
of your [Eloquent models](/docs/12.x/eloquent) using model factories.
|
||
|
||
To see an example of how to write a factory, take a look at the
|
||
`database/factories/UserFactory.php` file in your application. This factory is
|
||
included with all new Laravel applications and contains the following factory
|
||
definition:
|
||
|
||
|
||
|
||
1namespace Database\Factories;
|
||
|
||
2
|
||
|
||
3use Illuminate\Database\Eloquent\Factories\Factory;
|
||
|
||
4use Illuminate\Support\Facades\Hash;
|
||
|
||
5use Illuminate\Support\Str;
|
||
|
||
6
|
||
|
||
7/**
|
||
|
||
8 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
|
||
|
||
9 */
|
||
|
||
10class UserFactory extends Factory
|
||
|
||
11{
|
||
|
||
12 /**
|
||
|
||
13 * The current password being used by the factory.
|
||
|
||
14 */
|
||
|
||
15 protected static ?string $password;
|
||
|
||
16
|
||
|
||
17 /**
|
||
|
||
18 * Define the model's default state.
|
||
|
||
19 *
|
||
|
||
20 * @return array<string, mixed>
|
||
|
||
21 */
|
||
|
||
22 public function definition(): array
|
||
|
||
23 {
|
||
|
||
24 return [
|
||
|
||
25 'name' => fake()->name(),
|
||
|
||
26 'email' => fake()->unique()->safeEmail(),
|
||
|
||
27 'email_verified_at' => now(),
|
||
|
||
28 'password' => static::$password ??= Hash::make('password'),
|
||
|
||
29 'remember_token' => Str::random(10),
|
||
|
||
30 ];
|
||
|
||
31 }
|
||
|
||
32
|
||
|
||
33 /**
|
||
|
||
34 * Indicate that the model's email address should be unverified.
|
||
|
||
35 */
|
||
|
||
36 public function unverified(): static
|
||
|
||
37 {
|
||
|
||
38 return $this->state(fn (array $attributes) => [
|
||
|
||
39 'email_verified_at' => null,
|
||
|
||
40 ]);
|
||
|
||
41 }
|
||
|
||
42}
|
||
|
||
|
||
namespace Database\Factories;
|
||
|
||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||
use Illuminate\Support\Facades\Hash;
|
||
use Illuminate\Support\Str;
|
||
|
||
/**
|
||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
|
||
*/
|
||
class UserFactory extends Factory
|
||
{
|
||
/**
|
||
* The current password being used by the factory.
|
||
*/
|
||
protected static ?string $password;
|
||
|
||
/**
|
||
* Define the model's default state.
|
||
*
|
||
* @return array<string, mixed>
|
||
*/
|
||
public function definition(): array
|
||
{
|
||
return [
|
||
'name' => fake()->name(),
|
||
'email' => fake()->unique()->safeEmail(),
|
||
'email_verified_at' => now(),
|
||
'password' => static::$password ??= Hash::make('password'),
|
||
'remember_token' => Str::random(10),
|
||
];
|
||
}
|
||
|
||
/**
|
||
* Indicate that the model's email address should be unverified.
|
||
*/
|
||
public function unverified(): static
|
||
{
|
||
return $this->state(fn (array $attributes) => [
|
||
'email_verified_at' => null,
|
||
]);
|
||
}
|
||
}
|
||
|
||
As you can see, in their most basic form, factories are classes that extend
|
||
Laravel's base factory class and define a `definition` method. The
|
||
`definition` method returns the default set of attribute values that should be
|
||
applied when creating a model using the factory.
|
||
|
||
Via the `fake` helper, factories have access to the
|
||
[Faker](https://github.com/FakerPHP/Faker) PHP library, which allows you to
|
||
conveniently generate various kinds of random data for testing and seeding.
|
||
|
||
You can change your application's Faker locale by updating the `faker_locale`
|
||
option in your `config/app.php` configuration file.
|
||
|
||
## Defining Model Factories
|
||
|
||
### Generating Factories
|
||
|
||
To create a factory, execute the `make:factory` [Artisan
|
||
command](/docs/12.x/artisan):
|
||
|
||
|
||
|
||
1php artisan make:factory PostFactory
|
||
|
||
|
||
php artisan make:factory PostFactory
|
||
|
||
The new factory class will be placed in your `database/factories` directory.
|
||
|
||
#### Model and Factory Discovery Conventions
|
||
|
||
Once you have defined your factories, you may use the static `factory` method
|
||
provided to your models by the
|
||
`Illuminate\Database\Eloquent\Factories\HasFactory` trait in order to
|
||
instantiate a factory instance for that model.
|
||
|
||
The `HasFactory` trait's `factory` method will use conventions to determine
|
||
the proper factory for the model the trait is assigned to. Specifically, the
|
||
method will look for a factory in the `Database\Factories` namespace that has
|
||
a class name matching the model name and is suffixed with `Factory`. If these
|
||
conventions do not apply to your particular application or factory, you may
|
||
overwrite the `newFactory` method on your model to return an instance of the
|
||
model's corresponding factory directly:
|
||
|
||
|
||
|
||
1use Database\Factories\Administration\FlightFactory;
|
||
|
||
2
|
||
|
||
3/**
|
||
|
||
4 * Create a new factory instance for the model.
|
||
|
||
5 */
|
||
|
||
6protected static function newFactory()
|
||
|
||
7{
|
||
|
||
8 return FlightFactory::new();
|
||
|
||
9}
|
||
|
||
|
||
use Database\Factories\Administration\FlightFactory;
|
||
|
||
/**
|
||
* Create a new factory instance for the model.
|
||
*/
|
||
protected static function newFactory()
|
||
{
|
||
return FlightFactory::new();
|
||
}
|
||
|
||
Then, define a `model` property on the corresponding factory:
|
||
|
||
|
||
|
||
1use App\Administration\Flight;
|
||
|
||
2use Illuminate\Database\Eloquent\Factories\Factory;
|
||
|
||
3
|
||
|
||
4class FlightFactory extends Factory
|
||
|
||
5{
|
||
|
||
6 /**
|
||
|
||
7 * The name of the factory's corresponding model.
|
||
|
||
8 *
|
||
|
||
9 * @var class-string<\Illuminate\Database\Eloquent\Model>
|
||
|
||
10 */
|
||
|
||
11 protected $model = Flight::class;
|
||
|
||
12}
|
||
|
||
|
||
use App\Administration\Flight;
|
||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||
|
||
class FlightFactory extends Factory
|
||
{
|
||
/**
|
||
* The name of the factory's corresponding model.
|
||
*
|
||
* @var class-string<\Illuminate\Database\Eloquent\Model>
|
||
*/
|
||
protected $model = Flight::class;
|
||
}
|
||
|
||
### Factory States
|
||
|
||
State manipulation methods allow you to define discrete modifications that can
|
||
be applied to your model factories in any combination. For example, your
|
||
`Database\Factories\UserFactory` factory might contain a `suspended` state
|
||
method that modifies one of its default attribute values.
|
||
|
||
State transformation methods typically call the `state` method provided by
|
||
Laravel's base factory class. The `state` method accepts a closure which will
|
||
receive the array of raw attributes defined for the factory and should return
|
||
an array of attributes to modify:
|
||
|
||
|
||
|
||
1use Illuminate\Database\Eloquent\Factories\Factory;
|
||
|
||
2
|
||
|
||
3/**
|
||
|
||
4 * Indicate that the user is suspended.
|
||
|
||
5 */
|
||
|
||
6public function suspended(): Factory
|
||
|
||
7{
|
||
|
||
8 return $this->state(function (array $attributes) {
|
||
|
||
9 return [
|
||
|
||
10 'account_status' => 'suspended',
|
||
|
||
11 ];
|
||
|
||
12 });
|
||
|
||
13}
|
||
|
||
|
||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||
|
||
/**
|
||
* Indicate that the user is suspended.
|
||
*/
|
||
public function suspended(): Factory
|
||
{
|
||
return $this->state(function (array $attributes) {
|
||
return [
|
||
'account_status' => 'suspended',
|
||
];
|
||
});
|
||
}
|
||
|
||
#### "Trashed" State
|
||
|
||
If your Eloquent model can be [soft deleted](/docs/12.x/eloquent#soft-
|
||
deleting), you may invoke the built-in `trashed` state method to indicate that
|
||
the created model should already be "soft deleted". You do not need to
|
||
manually define the `trashed` state as it is automatically available to all
|
||
factories:
|
||
|
||
|
||
|
||
1use App\Models\User;
|
||
|
||
2
|
||
|
||
3$user = User::factory()->trashed()->create();
|
||
|
||
|
||
use App\Models\User;
|
||
|
||
$user = User::factory()->trashed()->create();
|
||
|
||
### Factory Callbacks
|
||
|
||
Factory callbacks are registered using the `afterMaking` and `afterCreating`
|
||
methods and allow you to perform additional tasks after making or creating a
|
||
model. You should register these callbacks by defining a `configure` method on
|
||
your factory class. This method will be automatically called by Laravel when
|
||
the factory is instantiated:
|
||
|
||
|
||
|
||
1namespace Database\Factories;
|
||
|
||
2
|
||
|
||
3use App\Models\User;
|
||
|
||
4use Illuminate\Database\Eloquent\Factories\Factory;
|
||
|
||
5
|
||
|
||
6class UserFactory extends Factory
|
||
|
||
7{
|
||
|
||
8 /**
|
||
|
||
9 * Configure the model factory.
|
||
|
||
10 */
|
||
|
||
11 public function configure(): static
|
||
|
||
12 {
|
||
|
||
13 return $this->afterMaking(function (User $user) {
|
||
|
||
14 // ...
|
||
|
||
15 })->afterCreating(function (User $user) {
|
||
|
||
16 // ...
|
||
|
||
17 });
|
||
|
||
18 }
|
||
|
||
19
|
||
|
||
20 // ...
|
||
|
||
21}
|
||
|
||
|
||
namespace Database\Factories;
|
||
|
||
use App\Models\User;
|
||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||
|
||
class UserFactory extends Factory
|
||
{
|
||
/**
|
||
* Configure the model factory.
|
||
*/
|
||
public function configure(): static
|
||
{
|
||
return $this->afterMaking(function (User $user) {
|
||
// ...
|
||
})->afterCreating(function (User $user) {
|
||
// ...
|
||
});
|
||
}
|
||
|
||
// ...
|
||
}
|
||
|
||
You may also register factory callbacks within state methods to perform
|
||
additional tasks that are specific to a given state:
|
||
|
||
|
||
|
||
1use App\Models\User;
|
||
|
||
2use Illuminate\Database\Eloquent\Factories\Factory;
|
||
|
||
3
|
||
|
||
4/**
|
||
|
||
5 * Indicate that the user is suspended.
|
||
|
||
6 */
|
||
|
||
7public function suspended(): Factory
|
||
|
||
8{
|
||
|
||
9 return $this->state(function (array $attributes) {
|
||
|
||
10 return [
|
||
|
||
11 'account_status' => 'suspended',
|
||
|
||
12 ];
|
||
|
||
13 })->afterMaking(function (User $user) {
|
||
|
||
14 // ...
|
||
|
||
15 })->afterCreating(function (User $user) {
|
||
|
||
16 // ...
|
||
|
||
17 });
|
||
|
||
18}
|
||
|
||
|
||
use App\Models\User;
|
||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||
|
||
/**
|
||
* Indicate that the user is suspended.
|
||
*/
|
||
public function suspended(): Factory
|
||
{
|
||
return $this->state(function (array $attributes) {
|
||
return [
|
||
'account_status' => 'suspended',
|
||
];
|
||
})->afterMaking(function (User $user) {
|
||
// ...
|
||
})->afterCreating(function (User $user) {
|
||
// ...
|
||
});
|
||
}
|
||
|
||
## Creating Models Using Factories
|
||
|
||
### Instantiating Models
|
||
|
||
Once you have defined your factories, you may use the static `factory` method
|
||
provided to your models by the
|
||
`Illuminate\Database\Eloquent\Factories\HasFactory` trait in order to
|
||
instantiate a factory instance for that model. Let's take a look at a few
|
||
examples of creating models. First, we'll use the `make` method to create
|
||
models without persisting them to the database:
|
||
|
||
|
||
|
||
1use App\Models\User;
|
||
|
||
2
|
||
|
||
3$user = User::factory()->make();
|
||
|
||
|
||
use App\Models\User;
|
||
|
||
$user = User::factory()->make();
|
||
|
||
You may create a collection of many models using the `count` method:
|
||
|
||
|
||
|
||
1$users = User::factory()->count(3)->make();
|
||
|
||
|
||
$users = User::factory()->count(3)->make();
|
||
|
||
#### Applying States
|
||
|
||
You may also apply any of your states to the models. If you would like to
|
||
apply multiple state transformations to the models, you may simply call the
|
||
state transformation methods directly:
|
||
|
||
|
||
|
||
1$users = User::factory()->count(5)->suspended()->make();
|
||
|
||
|
||
$users = User::factory()->count(5)->suspended()->make();
|
||
|
||
#### Overriding Attributes
|
||
|
||
If you would like to override some of the default values of your models, you
|
||
may pass an array of values to the `make` method. Only the specified
|
||
attributes will be replaced while the rest of the attributes remain set to
|
||
their default values as specified by the factory:
|
||
|
||
|
||
|
||
1$user = User::factory()->make([
|
||
|
||
2 'name' => 'Abigail Otwell',
|
||
|
||
3]);
|
||
|
||
|
||
$user = User::factory()->make([
|
||
'name' => 'Abigail Otwell',
|
||
]);
|
||
|
||
Alternatively, the `state` method may be called directly on the factory
|
||
instance to perform an inline state transformation:
|
||
|
||
|
||
|
||
1$user = User::factory()->state([
|
||
|
||
2 'name' => 'Abigail Otwell',
|
||
|
||
3])->make();
|
||
|
||
|
||
$user = User::factory()->state([
|
||
'name' => 'Abigail Otwell',
|
||
])->make();
|
||
|
||
[Mass assignment protection](/docs/12.x/eloquent#mass-assignment) is
|
||
automatically disabled when creating models using factories.
|
||
|
||
### Persisting Models
|
||
|
||
The `create` method instantiates model instances and persists them to the
|
||
database using Eloquent's `save` method:
|
||
|
||
|
||
|
||
1use App\Models\User;
|
||
|
||
2
|
||
|
||
3// Create a single App\Models\User instance...
|
||
|
||
4$user = User::factory()->create();
|
||
|
||
5
|
||
|
||
6// Create three App\Models\User instances...
|
||
|
||
7$users = User::factory()->count(3)->create();
|
||
|
||
|
||
use App\Models\User;
|
||
|
||
// Create a single App\Models\User instance...
|
||
$user = User::factory()->create();
|
||
|
||
// Create three App\Models\User instances...
|
||
$users = User::factory()->count(3)->create();
|
||
|
||
You may override the factory's default model attributes by passing an array of
|
||
attributes to the `create` method:
|
||
|
||
|
||
|
||
1$user = User::factory()->create([
|
||
|
||
2 'name' => 'Abigail',
|
||
|
||
3]);
|
||
|
||
|
||
$user = User::factory()->create([
|
||
'name' => 'Abigail',
|
||
]);
|
||
|
||
### Sequences
|
||
|
||
Sometimes you may wish to alternate the value of a given model attribute for
|
||
each created model. You may accomplish this by defining a state transformation
|
||
as a sequence. For example, you may wish to alternate the value of an `admin`
|
||
column between `Y` and `N` for each created user:
|
||
|
||
|
||
|
||
1use App\Models\User;
|
||
|
||
2use Illuminate\Database\Eloquent\Factories\Sequence;
|
||
|
||
3
|
||
|
||
4$users = User::factory()
|
||
|
||
5 ->count(10)
|
||
|
||
6 ->state(new Sequence(
|
||
|
||
7 ['admin' => 'Y'],
|
||
|
||
8 ['admin' => 'N'],
|
||
|
||
9 ))
|
||
|
||
10 ->create();
|
||
|
||
|
||
use App\Models\User;
|
||
use Illuminate\Database\Eloquent\Factories\Sequence;
|
||
|
||
$users = User::factory()
|
||
->count(10)
|
||
->state(new Sequence(
|
||
['admin' => 'Y'],
|
||
['admin' => 'N'],
|
||
))
|
||
->create();
|
||
|
||
In this example, five users will be created with an `admin` value of `Y` and
|
||
five users will be created with an `admin` value of `N`.
|
||
|
||
If necessary, you may include a closure as a sequence value. The closure will
|
||
be invoked each time the sequence needs a new value:
|
||
|
||
|
||
|
||
1use Illuminate\Database\Eloquent\Factories\Sequence;
|
||
|
||
2
|
||
|
||
3$users = User::factory()
|
||
|
||
4 ->count(10)
|
||
|
||
5 ->state(new Sequence(
|
||
|
||
6 fn (Sequence $sequence) => ['role' => UserRoles::all()->random()],
|
||
|
||
7 ))
|
||
|
||
8 ->create();
|
||
|
||
|
||
use Illuminate\Database\Eloquent\Factories\Sequence;
|
||
|
||
$users = User::factory()
|
||
->count(10)
|
||
->state(new Sequence(
|
||
fn (Sequence $sequence) => ['role' => UserRoles::all()->random()],
|
||
))
|
||
->create();
|
||
|
||
Within a sequence closure, you may access the `$index` or `$count` properties
|
||
on the sequence instance that is injected into the closure. The `$index`
|
||
property contains the number of iterations through the sequence that have
|
||
occurred thus far, while the `$count` property contains the total number of
|
||
times the sequence will be invoked:
|
||
|
||
|
||
|
||
1$users = User::factory()
|
||
|
||
2 ->count(10)
|
||
|
||
3 ->sequence(fn (Sequence $sequence) => ['name' => 'Name '.$sequence->index])
|
||
|
||
4 ->create();
|
||
|
||
|
||
$users = User::factory()
|
||
->count(10)
|
||
->sequence(fn (Sequence $sequence) => ['name' => 'Name '.$sequence->index])
|
||
->create();
|
||
|
||
For convenience, sequences may also be applied using the `sequence` method,
|
||
which simply invokes the `state` method internally. The `sequence` method
|
||
accepts a closure or arrays of sequenced attributes:
|
||
|
||
|
||
|
||
1$users = User::factory()
|
||
|
||
2 ->count(2)
|
||
|
||
3 ->sequence(
|
||
|
||
4 ['name' => 'First User'],
|
||
|
||
5 ['name' => 'Second User'],
|
||
|
||
6 )
|
||
|
||
7 ->create();
|
||
|
||
|
||
$users = User::factory()
|
||
->count(2)
|
||
->sequence(
|
||
['name' => 'First User'],
|
||
['name' => 'Second User'],
|
||
)
|
||
->create();
|
||
|
||
## Factory Relationships
|
||
|
||
### Has Many Relationships
|
||
|
||
Next, let's explore building Eloquent model relationships using Laravel's
|
||
fluent factory methods. First, let's assume our application has an
|
||
`App\Models\User` model and an `App\Models\Post` model. Also, let's assume
|
||
that the `User` model defines a `hasMany` relationship with `Post`. We can
|
||
create a user that has three posts using the `has` method provided by the
|
||
Laravel's factories. The `has` method accepts a factory instance:
|
||
|
||
|
||
|
||
1use App\Models\Post;
|
||
|
||
2use App\Models\User;
|
||
|
||
3
|
||
|
||
4$user = User::factory()
|
||
|
||
5 ->has(Post::factory()->count(3))
|
||
|
||
6 ->create();
|
||
|
||
|
||
use App\Models\Post;
|
||
use App\Models\User;
|
||
|
||
$user = User::factory()
|
||
->has(Post::factory()->count(3))
|
||
->create();
|
||
|
||
By convention, when passing a `Post` model to the `has` method, Laravel will
|
||
assume that the `User` model must have a `posts` method that defines the
|
||
relationship. If necessary, you may explicitly specify the name of the
|
||
relationship that you would like to manipulate:
|
||
|
||
|
||
|
||
1$user = User::factory()
|
||
|
||
2 ->has(Post::factory()->count(3), 'posts')
|
||
|
||
3 ->create();
|
||
|
||
|
||
$user = User::factory()
|
||
->has(Post::factory()->count(3), 'posts')
|
||
->create();
|
||
|
||
Of course, you may perform state manipulations on the related models. In
|
||
addition, you may pass a closure-based state transformation if your state
|
||
change requires access to the parent model:
|
||
|
||
|
||
|
||
1$user = User::factory()
|
||
|
||
2 ->has(
|
||
|
||
3 Post::factory()
|
||
|
||
4 ->count(3)
|
||
|
||
5 ->state(function (array $attributes, User $user) {
|
||
|
||
6 return ['user_type' => $user->type];
|
||
|
||
7 })
|
||
|
||
8 )
|
||
|
||
9 ->create();
|
||
|
||
|
||
$user = User::factory()
|
||
->has(
|
||
Post::factory()
|
||
->count(3)
|
||
->state(function (array $attributes, User $user) {
|
||
return ['user_type' => $user->type];
|
||
})
|
||
)
|
||
->create();
|
||
|
||
#### Using Magic Methods
|
||
|
||
For convenience, you may use Laravel's magic factory relationship methods to
|
||
build relationships. For example, the following example will use convention to
|
||
determine that the related models should be created via a `posts` relationship
|
||
method on the `User` model:
|
||
|
||
|
||
|
||
1$user = User::factory()
|
||
|
||
2 ->hasPosts(3)
|
||
|
||
3 ->create();
|
||
|
||
|
||
$user = User::factory()
|
||
->hasPosts(3)
|
||
->create();
|
||
|
||
When using magic methods to create factory relationships, you may pass an
|
||
array of attributes to override on the related models:
|
||
|
||
|
||
|
||
1$user = User::factory()
|
||
|
||
2 ->hasPosts(3, [
|
||
|
||
3 'published' => false,
|
||
|
||
4 ])
|
||
|
||
5 ->create();
|
||
|
||
|
||
$user = User::factory()
|
||
->hasPosts(3, [
|
||
'published' => false,
|
||
])
|
||
->create();
|
||
|
||
You may provide a closure-based state transformation if your state change
|
||
requires access to the parent model:
|
||
|
||
|
||
|
||
1$user = User::factory()
|
||
|
||
2 ->hasPosts(3, function (array $attributes, User $user) {
|
||
|
||
3 return ['user_type' => $user->type];
|
||
|
||
4 })
|
||
|
||
5 ->create();
|
||
|
||
|
||
$user = User::factory()
|
||
->hasPosts(3, function (array $attributes, User $user) {
|
||
return ['user_type' => $user->type];
|
||
})
|
||
->create();
|
||
|
||
### Belongs To Relationships
|
||
|
||
Now that we have explored how to build "has many" relationships using
|
||
factories, let's explore the inverse of the relationship. The `for` method may
|
||
be used to define the parent model that factory created models belong to. For
|
||
example, we can create three `App\Models\Post` model instances that belong to
|
||
a single user:
|
||
|
||
|
||
|
||
1use App\Models\Post;
|
||
|
||
2use App\Models\User;
|
||
|
||
3
|
||
|
||
4$posts = Post::factory()
|
||
|
||
5 ->count(3)
|
||
|
||
6 ->for(User::factory()->state([
|
||
|
||
7 'name' => 'Jessica Archer',
|
||
|
||
8 ]))
|
||
|
||
9 ->create();
|
||
|
||
|
||
use App\Models\Post;
|
||
use App\Models\User;
|
||
|
||
$posts = Post::factory()
|
||
->count(3)
|
||
->for(User::factory()->state([
|
||
'name' => 'Jessica Archer',
|
||
]))
|
||
->create();
|
||
|
||
If you already have a parent model instance that should be associated with the
|
||
models you are creating, you may pass the model instance to the `for` method:
|
||
|
||
|
||
|
||
1$user = User::factory()->create();
|
||
|
||
2
|
||
|
||
3$posts = Post::factory()
|
||
|
||
4 ->count(3)
|
||
|
||
5 ->for($user)
|
||
|
||
6 ->create();
|
||
|
||
|
||
$user = User::factory()->create();
|
||
|
||
$posts = Post::factory()
|
||
->count(3)
|
||
->for($user)
|
||
->create();
|
||
|
||
#### Using Magic Methods
|
||
|
||
For convenience, you may use Laravel's magic factory relationship methods to
|
||
define "belongs to" relationships. For example, the following example will use
|
||
convention to determine that the three posts should belong to the `user`
|
||
relationship on the `Post` model:
|
||
|
||
|
||
|
||
1$posts = Post::factory()
|
||
|
||
2 ->count(3)
|
||
|
||
3 ->forUser([
|
||
|
||
4 'name' => 'Jessica Archer',
|
||
|
||
5 ])
|
||
|
||
6 ->create();
|
||
|
||
|
||
$posts = Post::factory()
|
||
->count(3)
|
||
->forUser([
|
||
'name' => 'Jessica Archer',
|
||
])
|
||
->create();
|
||
|
||
### Many to Many Relationships
|
||
|
||
Like has many relationships, "many to many" relationships may be created using
|
||
the `has` method:
|
||
|
||
|
||
|
||
1use App\Models\Role;
|
||
|
||
2use App\Models\User;
|
||
|
||
3
|
||
|
||
4$user = User::factory()
|
||
|
||
5 ->has(Role::factory()->count(3))
|
||
|
||
6 ->create();
|
||
|
||
|
||
use App\Models\Role;
|
||
use App\Models\User;
|
||
|
||
$user = User::factory()
|
||
->has(Role::factory()->count(3))
|
||
->create();
|
||
|
||
#### Pivot Table Attributes
|
||
|
||
If you need to define attributes that should be set on the pivot /
|
||
intermediate table linking the models, you may use the `hasAttached` method.
|
||
This method accepts an array of pivot table attribute names and values as its
|
||
second argument:
|
||
|
||
|
||
|
||
1use App\Models\Role;
|
||
|
||
2use App\Models\User;
|
||
|
||
3
|
||
|
||
4$user = User::factory()
|
||
|
||
5 ->hasAttached(
|
||
|
||
6 Role::factory()->count(3),
|
||
|
||
7 ['active' => true]
|
||
|
||
8 )
|
||
|
||
9 ->create();
|
||
|
||
|
||
use App\Models\Role;
|
||
use App\Models\User;
|
||
|
||
$user = User::factory()
|
||
->hasAttached(
|
||
Role::factory()->count(3),
|
||
['active' => true]
|
||
)
|
||
->create();
|
||
|
||
You may provide a closure-based state transformation if your state change
|
||
requires access to the related model:
|
||
|
||
|
||
|
||
1$user = User::factory()
|
||
|
||
2 ->hasAttached(
|
||
|
||
3 Role::factory()
|
||
|
||
4 ->count(3)
|
||
|
||
5 ->state(function (array $attributes, User $user) {
|
||
|
||
6 return ['name' => $user->name.' Role'];
|
||
|
||
7 }),
|
||
|
||
8 ['active' => true]
|
||
|
||
9 )
|
||
|
||
10 ->create();
|
||
|
||
|
||
$user = User::factory()
|
||
->hasAttached(
|
||
Role::factory()
|
||
->count(3)
|
||
->state(function (array $attributes, User $user) {
|
||
return ['name' => $user->name.' Role'];
|
||
}),
|
||
['active' => true]
|
||
)
|
||
->create();
|
||
|
||
If you already have model instances that you would like to be attached to the
|
||
models you are creating, you may pass the model instances to the `hasAttached`
|
||
method. In this example, the same three roles will be attached to all three
|
||
users:
|
||
|
||
|
||
|
||
1$roles = Role::factory()->count(3)->create();
|
||
|
||
2
|
||
|
||
3$user = User::factory()
|
||
|
||
4 ->count(3)
|
||
|
||
5 ->hasAttached($roles, ['active' => true])
|
||
|
||
6 ->create();
|
||
|
||
|
||
$roles = Role::factory()->count(3)->create();
|
||
|
||
$user = User::factory()
|
||
->count(3)
|
||
->hasAttached($roles, ['active' => true])
|
||
->create();
|
||
|
||
#### Using Magic Methods
|
||
|
||
For convenience, you may use Laravel's magic factory relationship methods to
|
||
define many to many relationships. For example, the following example will use
|
||
convention to determine that the related models should be created via a
|
||
`roles` relationship method on the `User` model:
|
||
|
||
|
||
|
||
1$user = User::factory()
|
||
|
||
2 ->hasRoles(1, [
|
||
|
||
3 'name' => 'Editor'
|
||
|
||
4 ])
|
||
|
||
5 ->create();
|
||
|
||
|
||
$user = User::factory()
|
||
->hasRoles(1, [
|
||
'name' => 'Editor'
|
||
])
|
||
->create();
|
||
|
||
### Polymorphic Relationships
|
||
|
||
[Polymorphic relationships](/docs/12.x/eloquent-relationships#polymorphic-
|
||
relationships) may also be created using factories. Polymorphic "morph many"
|
||
relationships are created in the same way as typical "has many" relationships.
|
||
For example, if an `App\Models\Post` model has a `morphMany` relationship with
|
||
an `App\Models\Comment` model:
|
||
|
||
|
||
|
||
1use App\Models\Post;
|
||
|
||
2
|
||
|
||
3$post = Post::factory()->hasComments(3)->create();
|
||
|
||
|
||
use App\Models\Post;
|
||
|
||
$post = Post::factory()->hasComments(3)->create();
|
||
|
||
#### Morph To Relationships
|
||
|
||
Magic methods may not be used to create `morphTo` relationships. Instead, the
|
||
`for` method must be used directly and the name of the relationship must be
|
||
explicitly provided. For example, imagine that the `Comment` model has a
|
||
`commentable` method that defines a `morphTo` relationship. In this situation,
|
||
we may create three comments that belong to a single post by using the `for`
|
||
method directly:
|
||
|
||
|
||
|
||
1$comments = Comment::factory()->count(3)->for(
|
||
|
||
2 Post::factory(), 'commentable'
|
||
|
||
3)->create();
|
||
|
||
|
||
$comments = Comment::factory()->count(3)->for(
|
||
Post::factory(), 'commentable'
|
||
)->create();
|
||
|
||
#### Polymorphic Many to Many Relationships
|
||
|
||
Polymorphic "many to many" (`morphToMany` / `morphedByMany`) relationships may
|
||
be created just like non-polymorphic "many to many" relationships:
|
||
|
||
|
||
|
||
1use App\Models\Tag;
|
||
|
||
2use App\Models\Video;
|
||
|
||
3
|
||
|
||
4$videos = Video::factory()
|
||
|
||
5 ->hasAttached(
|
||
|
||
6 Tag::factory()->count(3),
|
||
|
||
7 ['public' => true]
|
||
|
||
8 )
|
||
|
||
9 ->create();
|
||
|
||
|
||
use App\Models\Tag;
|
||
use App\Models\Video;
|
||
|
||
$videos = Video::factory()
|
||
->hasAttached(
|
||
Tag::factory()->count(3),
|
||
['public' => true]
|
||
)
|
||
->create();
|
||
|
||
Of course, the magic `has` method may also be used to create polymorphic "many
|
||
to many" relationships:
|
||
|
||
|
||
|
||
1$videos = Video::factory()
|
||
|
||
2 ->hasTags(3, ['public' => true])
|
||
|
||
3 ->create();
|
||
|
||
|
||
$videos = Video::factory()
|
||
->hasTags(3, ['public' => true])
|
||
->create();
|
||
|
||
### Defining Relationships Within Factories
|
||
|
||
To define a relationship within your model factory, you will typically assign
|
||
a new factory instance to the foreign key of the relationship. This is
|
||
normally done for the "inverse" relationships such as `belongsTo` and
|
||
`morphTo` relationships. For example, if you would like to create a new user
|
||
when creating a post, you may do the following:
|
||
|
||
|
||
|
||
1use App\Models\User;
|
||
|
||
2
|
||
|
||
3/**
|
||
|
||
4 * Define the model's default state.
|
||
|
||
5 *
|
||
|
||
6 * @return array<string, mixed>
|
||
|
||
7 */
|
||
|
||
8public function definition(): array
|
||
|
||
9{
|
||
|
||
10 return [
|
||
|
||
11 'user_id' => User::factory(),
|
||
|
||
12 'title' => fake()->title(),
|
||
|
||
13 'content' => fake()->paragraph(),
|
||
|
||
14 ];
|
||
|
||
15}
|
||
|
||
|
||
use App\Models\User;
|
||
|
||
/**
|
||
* Define the model's default state.
|
||
*
|
||
* @return array<string, mixed>
|
||
*/
|
||
public function definition(): array
|
||
{
|
||
return [
|
||
'user_id' => User::factory(),
|
||
'title' => fake()->title(),
|
||
'content' => fake()->paragraph(),
|
||
];
|
||
}
|
||
|
||
If the relationship's columns depend on the factory that defines it you may
|
||
assign a closure to an attribute. The closure will receive the factory's
|
||
evaluated attribute array:
|
||
|
||
|
||
|
||
1/**
|
||
|
||
2 * Define the model's default state.
|
||
|
||
3 *
|
||
|
||
4 * @return array<string, mixed>
|
||
|
||
5 */
|
||
|
||
6public function definition(): array
|
||
|
||
7{
|
||
|
||
8 return [
|
||
|
||
9 'user_id' => User::factory(),
|
||
|
||
10 'user_type' => function (array $attributes) {
|
||
|
||
11 return User::find($attributes['user_id'])->type;
|
||
|
||
12 },
|
||
|
||
13 'title' => fake()->title(),
|
||
|
||
14 'content' => fake()->paragraph(),
|
||
|
||
15 ];
|
||
|
||
16}
|
||
|
||
|
||
/**
|
||
* Define the model's default state.
|
||
*
|
||
* @return array<string, mixed>
|
||
*/
|
||
public function definition(): array
|
||
{
|
||
return [
|
||
'user_id' => User::factory(),
|
||
'user_type' => function (array $attributes) {
|
||
return User::find($attributes['user_id'])->type;
|
||
},
|
||
'title' => fake()->title(),
|
||
'content' => fake()->paragraph(),
|
||
];
|
||
}
|
||
|
||
### Recycling an Existing Model for Relationships
|
||
|
||
If you have models that share a common relationship with another model, you
|
||
may use the `recycle` method to ensure a single instance of the related model
|
||
is recycled for all of the relationships created by the factory.
|
||
|
||
For example, imagine you have `Airline`, `Flight`, and `Ticket` models, where
|
||
the ticket belongs to an airline and a flight, and the flight also belongs to
|
||
an airline. When creating tickets, you will probably want the same airline for
|
||
both the ticket and the flight, so you may pass an airline instance to the
|
||
`recycle` method:
|
||
|
||
|
||
|
||
1Ticket::factory()
|
||
|
||
2 ->recycle(Airline::factory()->create())
|
||
|
||
3 ->create();
|
||
|
||
|
||
Ticket::factory()
|
||
->recycle(Airline::factory()->create())
|
||
->create();
|
||
|
||
You may find the `recycle` method particularly useful if you have models
|
||
belonging to a common user or team.
|
||
|
||
The `recycle` method also accepts a collection of existing models. When a
|
||
collection is provided to the `recycle` method, a random model from the
|
||
collection will be chosen when the factory needs a model of that type:
|
||
|
||
|
||
|
||
1Ticket::factory()
|
||
|
||
2 ->recycle($airlines)
|
||
|
||
3 ->create();
|
||
|
||
|
||
Ticket::factory()
|
||
->recycle($airlines)
|
||
->create();
|
||
|