В моем приложении есть таблица с именем «категории» с ограничением уникальности «имя_категории», я хочу вставить несколько строк в «категории».
Плохое решение:
foreach($categories as $category) {
Category::firstOrCreate(array('category_name' => $category['name']));
}
Это может быть решением, но оно не очень хорошее. Проблема в том, что когда будет много записей или тысячи записей, это приведет к большому количеству запросов к базе данных. что не хорошо.
Сравнительное решение Бертера
foreach($categories as $category){
$cats[] = array('category_name' => $category['name']);
}
Category::insert($cats);
Но когда я пытаюсь вставить дубликат «имя_категории», выдается исключение, и имя категории не вставляется.
Я знаю, что мы можем использовать INSERT IGNORE
но я ищу какое-то встроенное решение Laravel.
Я думаю, что это будет невозможно, потому что во втором случае будет выполнен один запрос, поэтому даже если вы обнаружите какую-либо ошибку, никакие данные не будут вставлены, потому что SQL-сервер откажет в этом из-за уникального ограничения. Я не думаю, что Laravel справится с этим.
Вероятно, что-то вроде этого — компромисс, чтобы решить это быстрее:
foreach($categories as $category){
$names[] = $category['name']
}
$dups = Category::whereIn('name', $names)->lists('name');
if ($dups) {
// here you can log or display message that some categories won't be inserted
}
$namesIns = [];
$cat = [];
foreach($categories as $category){
$item = ['category_name' => $category['name']];
if (!in_array($category['name'], $dups) && !in_array($item, $cat)) {
$cat[] = $item;
$namesIns[] = $category['name'];
}
}
Category::insert($cat);
$ids = Category::whereIn('name', $namesIns)->lists('id');
Других решений пока нет …