mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Fix orphaned records when running update
When DataObject::update() is run with relation fields and the relationship is new the relationship ID was not set on the DataObject. This patch fixes this. Fixes issue 6195 in open.silverstripe.org.
This commit is contained in:
parent
c1d25d17ce
commit
7f871fa18b
@ -772,10 +772,15 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
// no support for has_many or many_many relationships,
|
// no support for has_many or many_many relationships,
|
||||||
// as the updater wouldn't know which object to write to (or create)
|
// as the updater wouldn't know which object to write to (or create)
|
||||||
if($relObj->$relation() instanceof DataObject) {
|
if($relObj->$relation() instanceof DataObject) {
|
||||||
|
$parentObj = $relObj;
|
||||||
$relObj = $relObj->$relation();
|
$relObj = $relObj->$relation();
|
||||||
|
|
||||||
// If the intermediate relationship objects have been created, then write them
|
// If the intermediate relationship objects have been created, then write them
|
||||||
if($i<sizeof($relation)-1 && !$relObj->ID) $relObj->write();
|
if($i<sizeof($relation)-1 && !$relObj->ID || (!$relObj->ID && $parentObj != $this)) {
|
||||||
|
$relObj->write();
|
||||||
|
$relatedFieldName = $relation."ID";
|
||||||
|
$parentObj->$relatedFieldName = $relObj->ID;
|
||||||
|
$parentObj->write();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
user_error(
|
user_error(
|
||||||
"DataObject::update(): Can't traverse relationship '$relation'," .
|
"DataObject::update(): Can't traverse relationship '$relation'," .
|
||||||
@ -791,6 +796,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
if($relObj) {
|
if($relObj) {
|
||||||
$relObj->$fieldName = $v;
|
$relObj->$fieldName = $v;
|
||||||
$relObj->write();
|
$relObj->write();
|
||||||
|
$relatedFieldName = $relation."ID";
|
||||||
|
$this->$relatedFieldName = $relObj->ID;
|
||||||
$relObj->flushCache();
|
$relObj->flushCache();
|
||||||
} else {
|
} else {
|
||||||
user_error("Couldn't follow dot syntax '$k' on '$this->class' object", E_USER_WARNING);
|
user_error("Couldn't follow dot syntax '$k' on '$this->class' object", E_USER_WARNING);
|
||||||
|
@ -619,14 +619,14 @@ class DataObjectTest extends SapphireTest {
|
|||||||
* objects */
|
* objects */
|
||||||
$team1 = $this->objFromFixture('DataObjectTest_Team', 'team1');
|
$team1 = $this->objFromFixture('DataObjectTest_Team', 'team1');
|
||||||
$team1->CaptainID = $this->idFromFixture('DataObjectTest_Player', 'captain1');
|
$team1->CaptainID = $this->idFromFixture('DataObjectTest_Player', 'captain1');
|
||||||
|
|
||||||
$team1->update(array(
|
$team1->update(array(
|
||||||
'DatabaseField' => 'Something',
|
'DatabaseField' => 'Something',
|
||||||
'Captain.FirstName' => 'Jim',
|
'Captain.FirstName' => 'Jim',
|
||||||
'Captain.Email' => 'jim@example.com',
|
'Captain.Email' => 'jim@example.com',
|
||||||
'Captain.FavouriteTeam.Title' => 'New and improved team 1',
|
'Captain.FavouriteTeam.Title' => 'New and improved team 1',
|
||||||
));
|
));
|
||||||
|
|
||||||
/* Test the simple case of updating fields on the object itself */
|
/* Test the simple case of updating fields on the object itself */
|
||||||
$this->assertEquals('Something', $team1->DatabaseField);
|
$this->assertEquals('Something', $team1->DatabaseField);
|
||||||
|
|
||||||
@ -642,6 +642,29 @@ class DataObjectTest extends SapphireTest {
|
|||||||
$this->assertEquals('New and improved team 1', $reloadedTeam1->Title);
|
$this->assertEquals('New and improved team 1', $reloadedTeam1->Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDataObjectUpdateNew() {
|
||||||
|
/* update() calls can use the dot syntax to reference has_one relations and other methods that return
|
||||||
|
* objects */
|
||||||
|
$team1 = $this->objFromFixture('DataObjectTest_Team', 'team1');
|
||||||
|
$team1->CaptainID = 0;
|
||||||
|
|
||||||
|
$team1->update(array(
|
||||||
|
'Captain.FirstName' => 'Jim',
|
||||||
|
'Captain.FavouriteTeam.Title' => 'New and improved team 1',
|
||||||
|
));
|
||||||
|
/* Test that the captain ID has been updated */
|
||||||
|
$this->assertGreaterThan(0, $team1->CaptainID);
|
||||||
|
|
||||||
|
/* Fetch the newly created captain */
|
||||||
|
$captain1 = DataObjectTest_Player::get()->byID($team1->CaptainID);
|
||||||
|
$this->assertEquals('Jim', $captain1->FirstName);
|
||||||
|
|
||||||
|
/* Grab the favourite team and make sure it has the correct values */
|
||||||
|
$reloadedTeam1 = $captain1->FavouriteTeam();
|
||||||
|
$this->assertEquals($reloadedTeam1->ID, $captain1->FavouriteTeamID);
|
||||||
|
$this->assertEquals('New and improved team 1', $reloadedTeam1->Title);
|
||||||
|
}
|
||||||
|
|
||||||
public function testWritingInvalidDataObjectThrowsException() {
|
public function testWritingInvalidDataObjectThrowsException() {
|
||||||
$validatedObject = new DataObjectTest_ValidatedObject();
|
$validatedObject = new DataObjectTest_ValidatedObject();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user