Как я могу написать это так, чтобы оно попадало в базу данных только один раз?


Вот что у меня сейчас есть:

$sortOrder = ['0','1','4','2','3'];

$cards = ComboCard::where('username', '=', $user->username)
    ->where('combo_uid', '=', $comboUid)
    ->select('id', 'card_order')
    ->orderBy('card_order', 'ASC')
    ->get();

for($i=0; $i<count($cards); $i++) { // currently hits the database n times based on count($cards)
    $index = $sortOrder[$i];
    $cards[$index]->card_order = $i;
    $cards[$index]->save();
}
Author: rotaercz, 2015-05-18

1 answers

Если вам нужна отдельная инструкция для обновления, вам нужно case.

Тем не менее, вы не будете использовать Красноречивый , но необработанное соединение update (поскольку значения в этом массиве card_order - я бы использовал ids вместо этого):

$cases = $bindings = [];

foreach ($sortOrder as $new => $previous) {
  $cases[] = 'when ? then ?';
  $bindings[] = $previous;
  $bindings[] = $new;
}

// placeholders for the where in clause: ?,?,?,?,...
$placeholders = implode(',', array_fill(0, count($sortOrder), '?'));

// bindings for the where in clause
$bindings = array_merge($bindings, $sortOrder);

$sql = 'update `cards` set `card_order` = case `card_order` '.implode(' ', $cases).' end'.
       ' where `card_order` in ('.$placeholders.')';

DB::update($sql, $bindings);
 2
Author: Jarek Tkaczyk, 2015-05-18 20:42:14