Reputation: 201
I need to run a Factory 50
times, so inside the DatabseSeeder
:
public function run()
{
for($i=1;$i<=50;$i++){
(new CategoryQuestionFactory($i))->create();
}
}
So as you can see, I tried passing a variable called $i
as parameter to CategoryQuestionFactory
class.
Then at this Factory, I tried this:
class CategoryQuestionFactory extends Factory
{
protected $counter;
public function __construct($c)
{
$this->counter = $c;
}
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
$question = Question::find($this->counter);
return [
'category_id' => $this->faker->numberBetween(1,22),
'question_id' => $question->id
];
}
}
But when I run php artisan db:seed
at Terminal, I get this error:
Call to a member function pipe() on null
at C:\xampp\htdocs\forum\root\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Factories\Factory.php:429
So what's going wrong here? How can I properly send a value as a parameter to the Factory Class?
Also, at the IDE for the __construct
method of this Factory, I get this message:
Here is the capture of error at IDE:
Upvotes: 2
Views: 1160
Reputation: 4372
I've generated the model via PhpStrom:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Collection;
class CategoryQuestionFactory extends Factory
{
public function __construct($count = null, ?Collection $states = null, ?Collection $has = null, ?Collection $for = null, ?Collection $afterMaking = null, ?Collection $afterCreating = null, $connection = null, ?Collection $recycle = null)
{
parent::__construct($count, $states, $has, $for, $afterMaking, $afterCreating, $connection, $recycle);
}
public function definition()
{
$question = Question::find($this->counter);
return [
'category_id' => $this->faker->numberBetween(1,22),
'question_id' => $question->id
];
}
}
It's should work fine. I checked. You should call parent::__construct
.
Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body. Also like constructors, a child class may inherit the parent's destructor if it does not implement one itself.
Upvotes: 1
Reputation: 67
Don't forget to call parent::__construct()
in the constructor of your CategoryQuestionFactory
factory.
Your CategoryQuestionFactory
is supposed to extends Laravel standard Factory
. Missing to call the parent constructor on a child class breaks the code.
Upvotes: 1
Reputation: 671
In laravel its better to associate with the model, So instead of doing this
$question = Question::find($this->counter);
return [
'category_id' => $this->faker->numberBetween(1,22),
'question_id' => $question->id
];
you can do this (then you dont have to passs the $i
)
return [
'category_id' => $this->faker->numberBetween(1,22),
'question_id' => Question::factory(),
];
Upvotes: 0
Reputation: 1216
It seems to me that you want to seed the intermediate table. There are methods that can be use when seeding them one of them is has()
which is the one i always use.
/**
* will create a one question and 3 category then create a data in the intermediate table.
* expected data :
* question_id | category_id
* 1 1
* 1 2
* 1 3
*/
Question::factory()->has(
Category::factory()->count(3)
)->create();
So let's say you want to create a 100 question and 5 categories
/**
* will create a 100 question and 5 category then create a data in the intermediate table.
* expected data :
* question_id | category_id
* 1 1
* 1 2
* 1 3
* 1 4
* 1 5
* 2 1
* 2 2
* 2 3
* 2 4
* 2 5
* until the 100th question will have a 5 categories
*/
Question::factory(100)->has(
Category::factory()->count(5)
)->create();
Upvotes: 2