Обновление массы Laravel с другим значением в зависимости от условия - PullRequest
0 голосов
/ 21 сентября 2019

У меня есть структура таблицы, например:

id    //primary_key
value
changed_value    //on update value column should not be updated instead changed value should be updated
status    // 0 - default, 1- updated
am_id  //foreign_key

Теперь для массового обновления я делаю следующее:

Model::where('am_id',$request->am_id)
        ->where('value',$request->value)
        ->update([
                         'changed_value' => '$request->value',
                         'status' => 1
                ]);

Однако мы не должны устанавливать статус как 1 вслепую,так как есть одно условие.Если значение столбца value равно значению $request->value, вместо него должно быть 0.

Как может выглядеть этот сценарий?

Первоначально после вставки первой строкивыглядит как

+-----+-------+---------------+--------+-------+
| id  | value | changed_value | status | am_id |
+-----+-------+---------------+--------+-------+
|  1  | 20    | null          | 0      | 1     |  
+-----+-------+---------------+--------+-------+

После 1-го обновления

+-----+-------+---------------+--------+-------+
| id  | value | changed_value | status | am_id |
+-----+-------+---------------+--------+-------+
|  1  | 20    | 40            | 1      | 1     |   // changed_value - 40 , status 1
+-----+-------+---------------+--------+-------+

После 2-го обновления (скажем, значение обновлено до 20), в этом случае как value === changed_value статус должен быть обновленкак 0 не 1

+-----+-------+---------------+--------+-------+
| id  | value | changed_value | status | am_id |
+-----+-------+---------------+--------+-------+
|  1  | 20    | 20            | 0      | 1     |     // changed_value - 20 , status 0
+-----+-------+---------------+--------+-------+

Это означает, что во время обновления модели в приведенном ниже коде.Я хочу вставить условие, if( value == $request->value) status = 0 else status = 1

Model::where('am_id',$request->am_id)
        ->where('value',$request->value)
        ->update([
                     'changed_value' => '$request->value',
                      'status' => 1
                ]);

Ответы [ 3 ]

0 голосов
/ 21 сентября 2019

К сожалению, Eloquent не был разработан для обработки такого массового обновления (если вам нужны другие условия) с помощью одного запроса.Вам придется пройтись по моделям или прибегнуть к построителю запросов.

$models = Model::where('am_id',$request->am_id)->get();

$models->map(function ($model) use ($request) {

    // status
    $status = $model->value === $request->value ? 0 : 1;

    // update model
    $model->update([
        'changed_value' => $request->value,
        'status' => $status
    ]);

    return $model;
});

РЕДАКТИРОВАТЬ: на этой странице есть несколько идей для построителя запросов, которые могут позволить вам сделать что-то повторно используемое, вместо того, чтобы просто писать rawSQL в любое время, когда вам нужно это сделать.
https://github.com/laravel/ideas/issues/575#issuecomment-300731748

0 голосов
/ 21 сентября 2019

В качестве альтернативы вы всегда можете использовать raw sql, если производительность была проблемой.

DB::unprepared(' 
    update model 
    set status = case when (changed_value = "'.$request->value.'") then 0 else 1 end 
    and changed_value = "'.$request->value.'" 
    where value = "'.$request->value.'";
')

Редактировать: Вы можете сделать это в Eloquent с двумя запросами с подзапросом, чтобы отфильтровать идентификаторы уже обновленных строк.

// get ids of all matching status 1 but don't execute the query
$matches = Model::select('id')->where('am_id',$request->am_id)->where('value',$request->value)
    ->where('changed_value', $request->value);

// change matching status 1
Model::whereIn('id', $matches)
    ->update([
        'changed_value' => '$request->value',
        'status' => 1
    ]);

// matching not in status 1
Model::where('am_id',$request->am_id)
    ->where('value',$request->value)
    ->where('changed_value', '!=', $request->value)
    ->whereNotIn('id', $matches)
    ->update([
        'changed_value' => '$request->value',
        'status' => 0
    ]);
0 голосов
/ 21 сентября 2019

Попробуйте это.

$value = Model::where('am_id',$request->am_id)->first()->value;
if($request->value == $value){
    $status = 1;
}else{
    $status = 0;
}
Model::where('am_id',$request->am_id)
    ->update([
         'changed_value' => '$request->value',
         'status' => $status
    ]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...