Ookma-Kyi's avatar

Error seeding database

I am getting the following weird error:

   INFO  Seeding database.


   InvalidArgumentException 

  Unknown format "1"

  at vendor\fakerphp\faker\src\Faker\Generator.php:731
    727▕                 return $this->formatters[$format];
    728▕             }
    729▕         }
    730▕
  ➜ 731▕         throw new \InvalidArgumentException(sprintf('Unknown format "%s"', $format));
    732▕     }
    733▕
    734▕     /**
    735▕      * Replaces tokens ('{{ tokenName }}') with the result from the token method call

  1   vendor\fakerphp\faker\src\Faker\Generator.php:696
      Faker\Generator::getFormatter("1")

  2   vendor\fakerphp\faker\src\Faker\Generator.php:952
      Faker\Generator::format("1")

Here is my migration:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('belts', function (Blueprint $table) {
            $table->id();
            $table->string("name", 32)->unique();
            $table->string("image");
            $table->integer("min_xp");
            $table->integer("max_xp");
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('belts');
    }
};

Here is my model:

<?php

namespace App\Models;

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

class Belt extends Model
{
    use HasFactory;
}

Here is my factory:

<?php

namespace Database\Factories;

use App\Models\Belt;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends Factory<Belt>
 */
class BeltFactory extends Factory
{
    // Static variable to keep track of the last max XP
    protected static int $lastMaxXp = 0;

    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        // Set the minimum XP to be one more than the last max XP
        $minXp = self::$lastMaxXp + 1;

        // Generate a max XP that is greater than the min XP
        // For example, you can use a random number between min XP + 20 and min XP + 50
        $maxXp = $minXp + fake()->numberBetween(20, 50);

        // Update the last max XP for the next belt
        self::$lastMaxXp = $maxXp;

        return [
            'belt_id' => Belt::factory(),
            'name' => fake()->unique()->colorName,
            'image' => '',
            'min_xp' => fake()->$minXp,
            'max_xp' => fake()->$maxXp,
            'timestamp' => fake()->dateTime
        ];
    }
}

And here is the contents of DatabaseSeeder.php

<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use App\Models\Belt;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        // \App\Models\User::factory(10)->create();

        // \App\Models\User::factory()->create([
        //     'name' => 'Test User',
        //     'email' => '[email protected]',
        // ]);

        // create 6 samples of the belt instances
        Belt::factory(6)->create();
    }
}

Any ideas?

Update: I managed to track it down to this line: $minXp = self::$lastMaxXp + 1;

but, as that was code generated by the AI Larry Quickdraw, and I am a bit rusty on PHP I don't see the problem.

0 likes
2 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

It looks like there are a couple of issues in your BeltFactory that need to be addressed. Here's a step-by-step solution to fix the problems:

  1. In the BeltFactory, you are trying to use fake()->$minXp and fake()->$maxXp, which is incorrect. The fake() helper is used to generate fake data, and you should not use it to access variables. Instead, you should directly use the $minXp and $maxXp variables.

  2. The 'belt_id' => Belt::factory(), line in your factory is not necessary and is likely causing the error. This line is trying to create a new Belt instance for a belt_id field, which does not exist in your belts table schema. You should remove this line.

  3. The 'timestamp' => fake()->dateTime line is also incorrect. The timestamps() method in your migration already creates created_at and updated_at fields, which are automatically handled by Eloquent. You should remove this line as well.

Here's the corrected BeltFactory:

<?php

namespace Database\Factories;

use App\Models\Belt;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends Factory<Belt>
 */
class BeltFactory extends Factory
{
    // Static variable to keep track of the last max XP
    protected static int $lastMaxXp = 0;

    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        // Set the minimum XP to be one more than the last max XP
        $minXp = self::$lastMaxXp + 1;

        // Generate a max XP that is greater than the min XP
        // For example, you can use a random number between min XP + 20 and min XP + 50
        $maxXp = $minXp + $this->faker->numberBetween(20, 50);

        // Update the last max XP for the next belt
        self::$lastMaxXp = $maxXp;

        return [
            'name' => $this->faker->unique()->colorName,
            'image' => '', // You might want to use $this->faker to generate a fake image URL or path
            'min_xp' => $minXp,
            'max_xp' => $maxXp,
            // 'timestamp' => fake()->dateTime // Remove this line
        ];
    }
}

Make sure to remove the 'belt_id' and 'timestamp' lines from the factory definition array, and use the variables $minXp and $maxXp directly without the fake() helper.

After making these changes, try running the database seeder again with php artisan db:seed. This should seed your database without any errors.

sstier's avatar
        'min_xp' => fake()->$minXp,
        'max_xp' => fake()->$maxXp,

As the AI bot pointed out, seems as if this should be

        'min_xp' => $minXp,
        'max_xp' => $maxXp,

Please or to participate in this conversation.