首页 > 解决方案 > 如何让 laravel 工厂检查索引约束

问题描述

有人可以解释一下我做错了什么吗?我在键“user_id”和“place_id”的表 Ratings 中有一个索引约束。这个想法是有一个具有该 user_id 和 place_id 的唯一行。我的问题是关于工厂建设。我有这个:

    $factory->define(Rating::class, function (Faker $faker) {
        $user_id = User::all()->random()->id;
        $place_id = Place::all()->random()->id;
        $used = Rating::where([
            'user_id' => $user_id,
            'place_id' => $place_id
        ])->get();
//echo count($used);
        if (count($used) === 0) {
            return [
                'id' => $faker->uuid,
                'user_id' => $user_id,
                'place_id' => $place_id,
                'access' => rand(0, 5),
                'giftshops' => rand(0, 5),
                'location' => rand(0, 5),
                'restaurants' => rand(0, 5)
            ];
        } else {
            return [];
        }
    });

有时,只要种子很少,它就可以正常运行。但是当我尝试时,让我们说:

factory(Rating::class, 50)->create();

我总是最终遇到相应的错误:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '991b56c8-396b-33c5-8af1-ece8247dbb2e-4b514460-6da9-37ee-b3f8-181' for key 'only_one_user_per_place_rating' (SQL: 
insert into `ratings` (`id`, `user_id`, `place_id`, `access`, `giftshops`, `location`, `restaurants`) values (7f238084-3954-3be4-b3d6-e5f5d15e6b32, 991b56c8-396b-33c5-8af1-ece8247dbb2e, 
4b514460-6da9-37ee-b3f8-1814b6a7a968, 0, 0, 1, 1))

对于调试问题,我尝试回显计数值,并在控制台中得到如下值:00000001100010111001010001001000000101101001101111 然后它就坏了。

其他奇怪的是,零并不一定表示记录成功。

标签: phplaravelconstraintsfactoryseed

解决方案


做了一个可以满足我需求的解决方法。放弃工厂,在播种机上做了这些例程:

class RatingSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $used = [];
        for ($i = 0; $i < 50; $i++) {
            $user_id = User::all()->random()->id;
            $place_id = Place::all()->random()->id;
            $new = [
                'user_id' => $user_id,
                'place_id' => $place_id
            ];
            while (in_array($new, $used)) {
                $user_id = User::all()->random()->id;
                $place_id = Place::all()->random()->id;
                $new = [
                    'user_id' => $user_id,
                    'place_id' => $place_id
                ];
            }
            array_push($used,$new);
            $rating = new Rating;
            $rating->id = Str::uuid();
            $rating->user_id = $user_id;
            $rating->place_id = $place_id;
            $rating->access = rand(0, 5);
            $rating->giftshops = rand(0, 5);
            $rating->location = rand(0, 5);
            $rating->restaurants = rand(0, 5);
            $rating->save();
        }
    }
}

显然,这只适用于一次。始终牢记以前播种机中“地点”和“用户”的数量。如果用户/地点很少,这将是一个无限循环。


推荐阅读