#php #laravel-5.7
#php #laravel-5.7
Вопрос:
В Laravel существует два полезных метода в DB
facade:
insertOrIgnore()
— позволяет игнорировать действие при вставке дубликатаinsertUsing()
— позволяет вставлять данные на основе данных из других таблиц
Мне нужно объединить эти два подхода, т.е. вставить данные на основе существующих данных и игнорировать дубликаты. Знаете ли вы какой-либо способ сделать это в Laravel 5.7 или новее?
Ответ №1:
Для этого нет ни одного простого метода. Но этого можно достичь с помощью facade DB
.
Давайте предположим, что у нас есть 2 модели:
class Car extends Model
{
protected $table = "cars";
protected $fillable = [
"name",
"production_year",
];
}
class Antique extends Model
{
protected $table = "antiques";
protected $fillable = [
"name",
"production_year",
"category",
];
}
Предположим, что наша задача — найти все автомобили, созданные до 1990 года, и на их основе создать антиквариат с категорией ‘car’, игнорируя все автомобили, которые уже существуют в таблице антиквариат.
Это решение.
$selectQuery = Car::where('production_year', '<', 1990)->select([
'name',
'production_year',
DB::raw('"car" as category'),
]);
$antiquesTable = (new Antique())->getTable();
$insertQuery = "INSERT IGNORE INTO $antiquesTable (
`name`,
`production_year`,
`category`
) "
. $selectQuery->toSql();
DB::insert($insertQuery, $selectQuery->getBindings());
Это сгенерирует следующий SQL-запрос
INSERT IGNORE INTO antiques (`name`, `production_year`, `category`)
SELECT `name`, `production_year`, "car" AS category FROM cars WHERE `production_year` < 1990