skip to Main Content

I have a unique index on 3 fields:

public function up(): void
{
    Schema::create('items', function (Blueprint $table) {
        $table->id();
        $table->foreignId('points_id');
        $table->foreignId('user_id');
        $table->unsignedTinyInteger('status');
        $table->timestamp('created_at')->useCurrent();

        $table->foreign('user_id')->references('id')->on('users');
        $table->foreign('points_id')->references('id')->on('points');

        $table->unique(['points_id', 'user_id', 'status']);
    });
}

I need to make a factory to create a lot of items, but I can’t prevent the unique error if I create another item.

My laravel version is: ^9.52.10.

2

Answers


  1. Just based on your code, you should have a factory like this:

    <?php
    
    namespace DatabaseFactories;
    
    use AppModelsItem;
    use AppModelsPoint;
    use AppModelsUser;
    use IlluminateDatabaseEloquentFactoriesFactory;
    use IlluminateSupportStr;
    
    
    /**
     * @extends IlluminateDatabaseEloquentFactoriesFactory<Item>
     */
    class ItemFactory extends Factory
    {
        /**
         * Define the model's default state.
         *
         * @return array<string, mixed>
         */
        public function definition(): array
        {
            return [
                'points_id' => Point::factory(),
                'user_id' => User::factory(),
                'status' => fake()->boolean(),
            ];
        }
    }
    

    When you use Model::factory() and nothing else, it will, 100%, create a new model. You can see that on the documentation.

    Login or Signup to reply.
  2. I suggest to configure your ItemFactory to ignore duplication in unique columns:

    class ItemFactory extends Factory
    {
        protected $model = Item::class;
    
        public function definition()
        {
            return [
                'points_id' => function () {
                    return factory(AppModelsPoint::class)->create()->id;
                },
                'user_id' => function () {
                    return factory(AppModelsUser::class)->create()->id;
                },
                'status' => $this->faker->randomDigit,
            ];
        }
    
        public function configure()
        {
            return $this->afterCreating(function (Item $item) {
                try {
                    // Attempt to save the item
                    $item->save();
                } catch (IlluminateDatabaseQueryException $e) {
                   
                    $this->create();
                }
            });
        }
    }
    

    Factory callbacks are registered using the afterMaking and afterCreating methods and allow you to perform additional tasks after making or creating a model.

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