Commit 0899b8d4 by Carsten Brandt

changed updateAttributes to be more simple update

fixes #3233
parent 2cab70b0
...@@ -58,4 +58,8 @@ Upgrade from Yii 2.0 Beta ...@@ -58,4 +58,8 @@ Upgrade from Yii 2.0 Beta
* The behavior and signature of `ActiveRecord::afterSave()` has changed. `ActiveRecord::$isNewRecord` will now always be * The behavior and signature of `ActiveRecord::afterSave()` has changed. `ActiveRecord::$isNewRecord` will now always be
false in afterSave and also dirty attributes are not available. This change has been made to have a more consistent and false in afterSave and also dirty attributes are not available. This change has been made to have a more consistent and
expected behavior. The changed attributes are now available in the new parameter of afterSave() `$changedAttributes`. expected behavior. The changed attributes are now available in the new parameter of afterSave() `$changedAttributes`.
\ No newline at end of file
* `ActiveRecord::updateAttributes()` has been changed to not trigger events and not respect optimistic locking anymore to
differentiate it more from calling `update(false)` and to ensure it can be used in `afterSave()` without triggering infinite
loops.
\ No newline at end of file
...@@ -644,16 +644,16 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -644,16 +644,16 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* Updates the specified attributes. * Updates the specified attributes.
* *
* This method is a shortcut to [[update()]] when data validation is not needed * This method is a shortcut to [[update()]] when data validation is not needed
* and only a list of attributes need to be updated. * and only a small set attributes need to be updated.
* *
* You may specify the attributes to be updated as name list or name-value pairs. * You may specify the attributes to be updated as name list or name-value pairs.
* If the latter, the corresponding attribute values will be modified accordingly. * If the latter, the corresponding attribute values will be modified accordingly.
* The method will then save the specified attributes into database. * The method will then save the specified attributes into database.
* *
* Note that this method will NOT perform data validation. * Note that this method will **not** perform data validation and will **not** trigger events.
* *
* @param array $attributes the attributes (names or name-value pairs) to be updated * @param array $attributes the attributes (names or name-value pairs) to be updated
* @return integer|boolean the number of rows affected, or false if [[beforeSave()]] stops the updating process. * @return integer the number of rows affected.
*/ */
public function updateAttributes($attributes) public function updateAttributes($attributes)
{ {
...@@ -666,7 +666,19 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -666,7 +666,19 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
$attrs[] = $name; $attrs[] = $name;
} }
} }
return $this->updateInternal($attrs);
$values = $this->getDirtyAttributes($attributes);
if (empty($values)) {
return 0;
}
$rows = $this->updateAll($values, $this->getOldPrimaryKey(true));
foreach ($values as $name => $value) {
$this->_oldAttributes[$name] = $this->_attributes[$name];
}
return $rows;
} }
/** /**
......
...@@ -58,11 +58,11 @@ class Customer extends ActiveRecord ...@@ -58,11 +58,11 @@ class Customer extends ActiveRecord
})->orderBy('id'); })->orderBy('id');
} }
public function afterSave($insert) public function afterSave($insert, $changedAttributes)
{ {
ActiveRecordTest::$afterSaveInsert = $insert; ActiveRecordTest::$afterSaveInsert = $insert;
ActiveRecordTest::$afterSaveNewRecord = $this->isNewRecord; ActiveRecordTest::$afterSaveNewRecord = $this->isNewRecord;
parent::afterSave($insert); parent::afterSave($insert, $changedAttributes);
} }
/** /**
......
...@@ -40,11 +40,11 @@ class Customer extends ActiveRecord ...@@ -40,11 +40,11 @@ class Customer extends ActiveRecord
return $this->hasMany(OrderWithNullFK::className(), ['customer_id' => 'id'])->orderBy('created_at'); return $this->hasMany(OrderWithNullFK::className(), ['customer_id' => 'id'])->orderBy('created_at');
} }
public function afterSave($insert) public function afterSave($insert, $changedAttributes)
{ {
ActiveRecordTest::$afterSaveInsert = $insert; ActiveRecordTest::$afterSaveInsert = $insert;
ActiveRecordTest::$afterSaveNewRecord = $this->isNewRecord; ActiveRecordTest::$afterSaveNewRecord = $this->isNewRecord;
parent::afterSave($insert); parent::afterSave($insert, $changedAttributes);
} }
/** /**
......
...@@ -38,11 +38,11 @@ class Customer extends ActiveRecord ...@@ -38,11 +38,11 @@ class Customer extends ActiveRecord
/** /**
* @inheritdoc * @inheritdoc
*/ */
public function afterSave($insert) public function afterSave($insert, $changedAttributes)
{ {
ActiveRecordTest::$afterSaveInsert = $insert; ActiveRecordTest::$afterSaveInsert = $insert;
ActiveRecordTest::$afterSaveNewRecord = $this->isNewRecord; ActiveRecordTest::$afterSaveNewRecord = $this->isNewRecord;
parent::afterSave($insert); parent::afterSave($insert, $changedAttributes);
} }
/** /**
......
...@@ -816,7 +816,7 @@ trait ActiveRecordTestTrait ...@@ -816,7 +816,7 @@ trait ActiveRecordTestTrait
$this->afterSave(); $this->afterSave();
$this->assertNotNull($customer->id); $this->assertNotNull($customer->id);
$this->assertTrue(static::$afterSaveNewRecord); $this->assertFalse(static::$afterSaveNewRecord);
$this->assertTrue(static::$afterSaveInsert); $this->assertTrue(static::$afterSaveInsert);
$this->assertFalse($customer->isNewRecord); $this->assertFalse($customer->isNewRecord);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment