Search code examples
phplaravellaravel-seeding

laravel seeder is giving an error and won't seed


I've been trying to get my seeder to work but it keeps giving me the following error

 Call to undefined function Database\Seeders\factory()

  at database/seeders/ContactTableSeeder.php:16
     12▕      * @return void
     13▕      */
     14▕     public function run()
     15▕     {
  ➜  16▕         factory('App\Models\Contact', 100)->create()
     17▕         ->each(function($contact) {
     18▕             $contact->addresses()->save(
     19▕                 (factory(App\Address::class)->make())
     20▕             );

      +24 vendor frames 
  25  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

My DatabaseSeeder

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        //Model::unguard(); // Disable mass assignment

        $this->call(ContactTableSeeder::class);

        //Model::reguard();
    }
}

My ContactTableSeeder

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class ContactTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory('App\Models\Contact', 100)->create()
        ->each(function($contact) {
            $contact->addresses()->save(
                (factory(App\Address::class)->make())
            );
        });
    }
}

My ContactFactory

<?php

/* @var $factory \Illuminate\Database\Eloquent\Factory */

use App\Models\Contact;
use Faker\Generator as Faker;

$factory->define(Contact::class, function (Faker $faker) {
    return [
            'firstName' => $faker->firstName,
            'lastName' => $faker->lastName,
            'email' => $faker->unique()->email,
            'phone' => $faker->phoneNumber,
            'birthday' => $faker->date($format = 'Y-m-d', $max = 'now')
        ];
    });

My AddressFactory

<?php

/* @var $factory \Illuminate\Database\Eloquent\Factory */

use App\Models\Address;
use Faker\Generator as Faker;

$factory->define(Address::class, function (Faker $faker) {
    return [
        'number'    => $faker->number,
        'street'    => $faker->streetName,
        'city'      => $faker->city,
        'state'     => $faker->state,
        'zip'       => $faker->postcode,
        'type'      => 'home',
        'contact_id'=> factory(App\Models\Contact::class),
    ];
});

Contact Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;

use Illuminate\Database\Eloquent\Model;

class Contact extends Model
{
    use HasFactory;

    protected $fillable = [ 'firstName', 'lastName', 'email', 'phone', 'birthday' ];

    public function addresses()
    {
        return $this->hasMany('App\Models\Address');
    }
}

My Address Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Address extends Model
{
    use HasFactory;
    protected $fillable = [ 'id', 'number', 'street', 'city', 'state', 'zip', 'type', 'contact_id' ];

    public function contacts()
    {
        return $this->belongsTo('App\Models\Contact');
    }
}

I have tried running composer dump-auto composer update

None of those normal fixes seem to work.

I really have no idea why its failing Thanks in advance for your help


Solution

  • In Laravel8, you need to update your factory files like below or add laravel/legacy-factories package to your project. Further info: https://laravel.com/docs/8.x/upgrade#model-factories

    <?php
    
    namespace Database\Factories;
    
    use App\Models\Contact;
    use Illuminate\Database\Eloquent\Factories\Factory;
    
    class UserFactory extends Factory
    {
        /**
         * The name of the factory's corresponding model.
         *
         * @var string
         */
        protected $model = Contact::class;
    
        /**
         * Define the model's default state.
         *
         * @return array
         */
        public function definition()
        {
            return [
                'firstName' => $this->faker->firstName,
                'lastName' => $this->faker->lastName,
                'email' => $this->faker->unique()->email,
                'phone' => $this->faker->phoneNumber,
                'birthday' => $this->faker->date($format = 'Y-m-d', $max = 'now')
            ];
        }
    }
    

    In seeders use factory like that:

    <?php
    
    namespace Database\Seeders;
    
    use Illuminate\Database\Seeder;
    
    class ContactTableSeeder extends Seeder
    {
        /**
         * Run the database seeds.
         *
         * @return void
         */
        public function run()
        {
            App\Models\Contact::factory()->create(100)
                ->each(function($contact) {
                    $contact->addresses()->save(
                        App\Address::factory()->make()
                    );
            });
        }
    }