简体   繁体   中英

Yii2 set attribute value of all models in an array of models

Is there a way in yii2 to set one specific attribute value in all models in an array of models (of the same class)? I have searched but unfortunately found nothing relevant. Thanks in advance!

You can use Model::loadMultiple( $models, $data, $formName = null );

This is an example of how you can do that:

$numberOfModelsInArray = sizeof($myDataArray);
$myModels = [];
for ($i = 0; $i < $numberOfModelsInArray; $i++) {
     $myModels[] = new myModelForm();
}

VariantsForm::loadMultiple($myModels, $myDataArray, '');

To know more about loadMultiple() you can check https://www.yiiframework.com/doc/api/2.0/yii-base-model#loadMultiple()-detail for the documentation

Instead of a classical foreach loop you can also use array_walk :

\array_walk($carArray, function(&$car) { $car->engine = 'electric'; });

Another way would be to use Model::loadMultiple with a repeated array:

Model::loadMultiple(
    $carArray,
    \array_fill(0, count($carArray), ['engine' => 'electric']),
    ''
);

The last parameter is an empty string to make Yii expect the exact structure of the second parameter.


Outdated after clarification:

There is a static method on ActiveRecord called updateAll :

Car::updateAll(['engine' => 'electric'], ['manufacturer' => 'Tesla']);
// UPDATE car SET engine = 'electric' WHERE 'manufacturer' = 'Tesla'

This will set the engine attribute of all cars manufactured by Tesla to 'electric' . If you do not specify the condition in the second argument, all cars will get updated.

If you absolutely need to do this for a processed array, you could map the primary key values and pass those as a value instead. Your condition will then be turned into a WHERE id IN(...) .

$carArray = [$car1, $car2, $car3];
$carArrayIds = \array_map(function ($car) {
    return $car->id;
}, $carArray);

Car::updateAll(['engine' => 'electric'], ['id' => $carArrayIds]);
// UPDATE car SET engine = 'electric' WHERE 'id' IN (1, 2, 3)

And, last but not least, if none of this is possible, try updating all the models in a single database transaction.

$transaction = Yii::$app->db->beginTransaction();
try {
    foreach ($carArray as $car) {
        $car->engine = 'electric';
        if ($car->update() !== 1) {
            throw new \RuntimeException('Single car update failed');
        }
    }
} catch (\Exception $e) {
    $transaction->rollback();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM