Laravel 播种 - 独特的用户和教师 ID 对

问题描述 投票:0回答:4

我在 Laravel 5.1 中使用数据库迁移和播种。

迁移

public function up()
{
    Schema::create('teachers', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id')->unsigned();
        $table->integer('teacher_id')->unsigned();
        $table->boolean('disable')->default(0);
        $table->timestamps();

        $table->unique(['user_id', 'teacher_id']);

        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        $table->foreign('teacher_id')->references('id')->on('users')->onDelete('cascade');
    });
}

*** user_id 和 Teacher_id 必须是唯一的。

模型工厂

$factory->define(App\Teacher::class, function ($faker) {
    return [
        'user_id'           => $faker->numberBetween(1, 59),
        'teacher_id'        => $faker->numberBetween(1, 59),
    ];
});

我在

DatabaseSeeder.php
中设置了用于生成 500 个教师关系的播种器:
factory(App\Teacher::class, 500)->create();

但是我收到了这个错误:

[PDOException] 
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '10-11' for key 'teachers_user_id_teacher_id_ 
unique'

如您所见,***(唯一属性)导致了错误。 有什么办法可以解决吗?你的想法是什么?

php laravel laravel-5.1 laravel-migrations laravel-seeding
4个回答
2
投票

您可以获取

User
模型的集合,然后在
while
循环中从该集合中的随机 ID 中分配对:

$users = User::all(['id']);

while ($users->count() > 1) {
    // Get random user for a teacher, and remove from collection
    $teacher = $users->random();
    $users->pull($teacher->getKey());

    // Get random user and remove from collection
    $user = $users->random();
    $users->pull($user->getKey());

    Teacher::create([
        'user_id' => $user->getKey(),
        'teacher_id' => $teacher->getKey(),
    ]);
}

0
投票

如果数据库中存在唯一记录,您可以抛出异常。然后在 Seeder 类中,使用 try-catch 块,捕获异常不执行任何操作。如果遇到现有记录,则应继续播种。

示例:假设

product_stocks
表中有 3 列,其中
product_id
color_id
size_id
是唯一的。

工厂类:

/**
 * Define the model's default state.
 *
 * @return array
 */
public function definition()
{
    $productId = $this->faker->randomElement(Product::pluck('id')->toArray());
    $colorId = $this->faker->randomElement(Color::pluck('id')->toArray());
    $sizeId = $this->faker->randomElement(Size::pluck('id')->toArray());

    $exists = ProductStock::where([
        ['product_id', '=', $productId],
        ['color_id', '=', $colorId],
        ['size_id', '=', $sizeId],
    ])->exists();

    if ($exists) {
        throw new Exception('duplicate value');
    }

    return [
        'product_id' => $productId,
        'color_id' => $colorId,
        'size_id' => $sizeId,
        'stok_ready' => $this->faker->numberBetween(0, 100),
    ];
}

播种者类别:

/**
 * Run the database seeds.
 *
 * @return void
 */
public function run()
{
    try {
        ProductStock::factory()
            ->count(Product::count() * rand(5, 10))
            ->create();
    } catch (Exception $e) {
        // do something
    }
}

0
投票

使用

unique
方法尝试此解决方案:

$factory->define(App\Teacher::class, function ($faker) {
    return [
        'user_id' => User::all()->unique()->random()->id,
        'teacher_id' => Teacher::all()->unique()->random()->id,
    ];
});

-1
投票
/**@var array $unique*/

$repeatRandom =  static function () use (&$unique, &$repeatRandom) {
    $userId = User::pluck('id')->random();
    $teacherId = User::pluck('id')->random();
    $newPair = [
        $userId, $teacherId
    ];

    foreach ($unique as $items) {
        if (!array_diff_assoc($items, $newPair)) {
            return $repeatRandom($unique);
        }
    }
    return $newPair;
};


$factory->define(Teacher::class, static function (Faker $faker) use (&$unique, &$repeatRandom) {

    $userId = User::pluck('id')->random();
    $teacherId = User::pluck('id')->random();

    $newPair = [
        $userId, $teacherId
    ];

    if (is_array($unique)) {
        foreach ($unique as $items) {
            if (!array_diff_assoc($items, $newPair)) {
                $newPair = $repeatRandom($unique);
            }
        }
    }

    $unique[]  = $newPair;
    return [
        'user_id' => $newPair[0],
        'teacher_id' => $newPair[1]
    ];  
}


© www.soinside.com 2019 - 2024. All rights reserved.