Skip to content
This repository has been archived by the owner on Jul 1, 2022. It is now read-only.

Commit

Permalink
Fix a regression in Has One saving introduced by #33 fix.
Browse files Browse the repository at this point in the history
  • Loading branch information
Alban Jubert committed Aug 10, 2018
1 parent 1fb2208 commit 9f657bd
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Yii2 Active Record Save Relations Behavior Change Log

## [1.5.2]
### Fixed
- Fix a regression in Has One saving introduced by #33 fix.

## [1.5.1]
### Fixed
- Bug #33: Custom relation scenario was set too late and was preventing attributes from being correctly set (thx @phrakon)
Expand Down
41 changes: 29 additions & 12 deletions src/SaveRelationsBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -296,16 +296,7 @@ public function beforeValidate(ModelEvent $event)
// If relation is has_one, try to set related model attributes
foreach ($this->_relations as $relationName) {
if (array_key_exists($relationName, $this->_oldRelationValue)) { // Relation was not set, do nothing...
/** @var ActiveQuery $relation */
$relation = $model->getRelation($relationName);
if ($relation->multiple === false && !empty($model->{$relationName})) {
Yii::debug("Setting foreign keys for {$relationName}", __METHOD__);
foreach ($relation->link as $relatedAttribute => $modelAttribute) {
if ($model->{$modelAttribute} !== $model->{$relationName}->{$relatedAttribute}) {
$model->{$modelAttribute} = $model->{$relationName}->{$relatedAttribute};
}
}
}
$this->_setRelationForeignKeys($relationName);
}
}
}
Expand Down Expand Up @@ -384,9 +375,13 @@ protected function isModelTransactional(BaseActiveRecord $model)
*/
private function _prepareHasOneRelation(BaseActiveRecord $model, $relationName, ModelEvent $event)
{
Yii::debug("_prepareHasOneRelation for {$relationName}", __METHOD__);
$relationModel = $model->{$relationName};
$this->validateRelationModel(self::prettyRelationName($relationName), $relationName, $model->{$relationName});
if ($relationModel->getIsNewRecord()) {
$relation = $model->getRelation($relationName);
$p1 = $model->isPrimaryKey(array_keys($relation->link));
$p2 = $relationModel::isPrimaryKey(array_values($relation->link));
if ($relationModel->getIsNewRecord() && $p1 && !$p2) {
// Save Has one relation new record
if ($event->isValid && (count($model->dirtyAttributes) || $model->{$relationName}->isNewRecord)) {
Yii::debug('Saving ' . self::prettyRelationName($relationName) . ' relation model', __METHOD__);
Expand Down Expand Up @@ -464,6 +459,29 @@ private function _rollback()
}
}

/**
* Set relation foreign keys that point to owner primary key
* @param $relationName
*/
protected function _setRelationForeignKeys($relationName)
{
/** @var BaseActiveRecord $owner */
$owner = $this->owner;
/** @var ActiveQuery $relation */
$relation = $owner->getRelation($relationName);
if ($relation->multiple === false && !empty($owner->{$relationName})) {
Yii::debug("Setting foreign keys for {$relationName}", __METHOD__);
foreach ($relation->link as $relatedAttribute => $modelAttribute) {
if ($owner->{$modelAttribute} !== $owner->{$relationName}->{$relatedAttribute}) {
if ($owner->{$relationName}->isNewRecord) {
$owner->{$relationName}->save();
}
$owner->{$modelAttribute} = $owner->{$relationName}->{$relatedAttribute};
}
}
}
}

/**
* Link the related models.
* If the models have not been changed, nothing will be done.
Expand Down Expand Up @@ -642,7 +660,6 @@ private function _afterSaveHasOneRelation($relationName)
{
/** @var BaseActiveRecord $owner */
$owner = $this->owner;

if ($this->_oldRelationValue[$relationName] !== $owner->{$relationName}) {
if ($owner->{$relationName} instanceof BaseActiveRecord) {
$owner->link($relationName, $owner->{$relationName});
Expand Down
2 changes: 1 addition & 1 deletion tests/SaveRelationsBehaviorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ public function testSaveHasOneReplaceRelatedWithNewRecord()
$profile->loadRelations($data);
$this->assertEquals('Someone Else', $profile->user->username, "User name should be 'Someone Else'");
$this->assertTrue($profile->user->isNewRecord, "User should be a new record");
$profile->save();
$this->assertEquals(1, $profile->user_id);
$this->assertTrue($profile->save(), 'Profile could not be saved');
$this->assertEquals('Someone Else', $profile->user->username, "User name should be 'Someone Else'");
}
Expand Down
3 changes: 3 additions & 0 deletions tests/models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
namespace tests\models;

use lhs\Yii2SaveRelationsBehavior\SaveRelationsBehavior;
use lhs\Yii2SaveRelationsBehavior\SaveRelationsTrait;

class User extends \yii\db\ActiveRecord
{
use SaveRelationsTrait;

/**
* @inheritdoc
*/
Expand Down

0 comments on commit 9f657bd

Please sign in to comment.