Reputation: 396
I'm overriding the create
method on a few of my models, like in this question. The problem I'm finding is that factories for these models fail because they aren't calling my custom create
method.
Model code:
class Teacher extends Model {
public static function create(array $attributes)
{
$user = User::create(['name' => $attributes['name']);
return static::query()->create(['budget' => $attributes['budget', 'user_id' => $user->id]);
}
Factory code:
$factory->define(App\Teacher::class, function(Faker $faker) {
return [
'name' => $faker->firstName(),
'budget' => $faker->numberBetween(100, 1000)
];
}
I get the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'name' in 'field list' (SQL: insert into `teachers` (`name`, `budget`, `updated_at`, `created_at`) values (Audreanne, 600, 2020-04-07 16:43:54, 2020-04-07 16:43:54))
Any help is greatly appreciated!
Upvotes: 1
Views: 2980
Reputation: 2327
Answer
Factories do not use the model create method to create the model it uses the save
method. You should change your factory to be like the below:
$factory->define(App\Teacher::class, function(Faker $faker) {
return [
'user_id' => function () {
return factory(App\User::class)->create()->id;
},
'budget' => $faker->numberBetween(100, 1000)
];
});
You should have a UserFactory.php
already that will generate a name for the associated user.
Additional Advice
As for overriding the create function on your model I strongly do not recommend this approach.
And where you are creating your teacher
in code I would recommend taking this approach:
// For example in TeacherController::store
$budget = 500;
$user_id = User::create(['name' => 'Peter Griffin'])->id;
$teacher = Teacher::create(compact('budget', 'user_id'));
If you find that you are needing to do this code in multiple places then I would suggest implementing a new method on your model (see below) or create a service class to handle it:
class Teacher extends Model {
public static function createWithUser($name, $budget): Teacher
{
$user_id = User::create(compact('name'))->id;
return Teacher::create(compact('budget', 'user_id'));
}
}
// For example
$teacher = Teacher::createWithUser('Peter Griffin', 500);
Upvotes: 3