У меня есть уникальное ограничение в моей базе данных для двух столбцов.
$table->unique(array("table_a_id", "table_b_id"));
Теперь я использую Faker в классе сеялки, чтобы заполнить эту сводную таблицу:
$tableAIds = TableA::all()->lists("id")->toArray();
$tableBIds = TableB::all()->lists("id")->toArray();
foreach(range(1, 20) as $index) {
$tableAId = $faker->randomElement($tableAIds);
$tableBId = $faker->randomElement($tableBIds);
DB::table("table_a_table_b_pivot")->insert([
"table_a_id" => $tableAId,
"table_b_id" => $tableBId
]);
}
Однако это создает дубликаты, и заполнение не выполняется из-за ошибки SQL.
Как мне убедиться, что я не пытаюсь вставить дубликаты?
Вы можете использовать это:
$tableAIds = TableA::all()->lists("id")->toArray();
$tableBIds = TableB::all()->lists("id")->toArray();
foreach (range(1, 20) as $index) {
repeat:
$tableAId = $faker->randomElement($tableAIds);
$tableBId = $faker->randomElement($tableBIds);
try {
DB::table("table_a_table_b_pivot")->insert([
"table_a_id" => $tableAId,
"table_b_id" => $tableBId,
]);
} catch (\Illuminate\Database\QueryException $e) {
//look for integrity violation exception (23000)
if($e->errorInfo[0]==23000)
goto repeat;
}
}
PS: Это может не сработать, если исходные данные TableA и TableB не соответствуют друг другу (то есть из этих данных невозможно сформировать 20 уникальных пар).
$unique = $faker->unique()->regexify('[0-4][0-9][0-4][0-9]');
Приведенный выше код приведет к появлению строки, состоящей из двух чисел от 0 до 49, которая никогда не повторяется. Теперь вы можете разбить на две части и надежно заполнить базу данных.
$firstId = ltrim(substr($unique, 0, 2), '0') + 1;
$secondId = ltrim(substr($unique, 2, 2), '0') + 1;
Два числа могут быть одинаковыми в строке, но строка всегда будет уникальной. Не забудьте добавить по одному для каждой части, потому что мы не хотим (и не можем) заполнять нашу базу данных нулями.
Вместо того, чтобы использовать фейкер, используйте коллекцию random
метод:
$tableAIds = TableA::all()->lists('id')->random(20);
$tableBIds = TableB::all()->lists('id')->random(20);
foreach(range(0, 19) as $index) {
DB::table("table_a_table_b_pivot")->insert([
"table_a_id" => $tableAIds[$index],
"table_b_id" => $tableBIds[$index],
]);
}
Отрегулируйте это в соответствии с вашими потребностями.
Например, это может быть то, что вы действительно хотите:
$tableAIds = TableA::all()->lists('id');
$tableBIds = TableB::all()->lists('id');
foreach ($tableAIds->random(5) as $tableAId) {
foreach ($tableBIds->random(2) as $tableBId) {
DB::table("table_a_table_b_pivot")->insert([
"table_a_id" => $tableAId,
"table_b_id" => $tableBId,
]);
}
}
Что бы это ни было, играйте с этим сами. Нет необходимости для мошенника здесь.