skip to Main Content

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:xampphtdocsforumrootvendorlaravelframeworksrcIlluminateDatabaseEloquentFactoriesFactory.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:

enter image description here


UPDATE #1:

Here is the capture of error at IDE:

enter image description here

4

Answers


  1. 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();
    
    Login or Signup to reply.
  2. 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(),
    ];
    
    Login or Signup to reply.
  3. 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.

    Login or Signup to reply.
  4. I’ve generated the model via PhpStrom:

    namespace AppModels;
    
    use IlluminateDatabaseEloquentFactoriesFactory;
    use IlluminateSupportCollection;
    
    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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search