Yurii
Yurii

Reputation: 11

Problem with Laravel 8: Call to a member function count() on null

I'm a newcomer to Laravel, and I got errors when I tried to generate some info in the table in the database using a factory.

Call to a member function count() on null " at vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/HasFactory.php:17.

Maybe somebody had the same problem? I will be grateful if someone can help. Below will be the code of certain elements:

Seeder

class UsersTableSeeder extends Seeder
{
    public function run()
    {
        Users::factory()->count(30)->create();
    }
}

Factory

class UploadInfoFactory extends Factory
{
    protected $model = Users::class;

    public function definition()
    {
        return [
            'Name' => $this->faker->name,
            'Birthday' => $this->faker->date('d-m-Y'),
            'Phone number' => $this->faker->phoneNumber,
            'Phone balance' => $this->faker->numberBetween(-50,150),
        ];
    }
}

DatabaseSeeder

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $this->call(UsersTableSeeder::class);
    }
}

Migration

class CreateInfoUsers extends Migration
{
    public function up()
    {
        Schema::create('info_users', function (Blueprint $table) {
            $table->integerIncrements('id');
            $table->string('name',100);
            $table->date('Birthday');
            $table->string('Phone number',100);
            $table->string('Phone balance',100);
        });
    }
}  

The error code that pops up in bash when we enter php artisan db: seed:

Call to a member function count() on null at vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/HasFactory.php:17
     13▕     public static function factory(...$parameters): Factory {
     14▕         $factory = static::newFactory() ?: Factory::factoryForModel(get_called_class());
     15▕ 
     16▕         return $factory
  ➜  17▕                     ->count(is_numeric($parameters[0] ?? null) ? $parameters[0] : null)
     18▕                     ->state(is_array($parameters[0] ?? null) ? $parameters[0] : ($parameters[1] ?? []));
     19▕     }
     20▕ 
     21▕     /**

Upvotes: 1

Views: 4282

Answers (2)

Gabriele Serra
Gabriele Serra

Reputation: 531

This might help someone else cause my problem was different. When seeding the database, Laravel printed out the same error that @Yurii experienced.

Seeding: Database\Seeders\ProfileSeeder

   Error 

  Call to a member function count() on null

  at vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/HasFactory.php:18

Indeed my artisan console failed to create the Factory for my Profile model

$ php artisan tinker
>>> use Illuminate\Database\Eloquent\Factories\Factory;
>>> Factory::factoryForModel(Profile::class);
=> null

After some minutes of investigation, I found out that I forgot to return the Factory in the configure method

class ProfileFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Profile::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            // some stuff
        ];
    }

    public function configure()
    {

        // it miss the return here !!
        $this->afterCreating(function (Profile $profile) {
            // do stuff with $profile
        });
    }
}

So, when the Factory was instantiated, the configure method was called but no Factory was returned! Placing the return fixed the issue.

Upvotes: 15

lagbox
lagbox

Reputation: 50561

If you want a model to automatically use a factory you would have to name the factory in a particular way, otherwise you would have to define a way to resolve the particular factory you want to use for the model.

Rename your factory to UsersFactory and it will automatically be used be the Users model.

Though, I suggest renaming Users to User as the convention is for models to be in the singular and tables to be in the plural. If you change the model name you would then need to change the factory to UserFactory to match.

"The HasFactory trait's factory method will use conventions to determine the proper factory for the model. 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"

Laravel 8.x Docs - Database Testing - Creating Models Using Factories - Connecting Factories and Models

Upvotes: 1

Related Questions