From b92b2a5887193cc89572b0dafbaef77177ce3b37 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Fri, 15 Aug 2008 03:08:03 +0000 Subject: [PATCH] Fixed saving of blank values to the has_one relations on versioned objects git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@60830 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- core/model/DataObject.php | 13 ++++++++--- tests/DataObjectTest.php | 48 +++++++++++++++++++++++++++++++-------- tests/SiteTreeTest.php | 14 ++++++++++++ 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/core/model/DataObject.php b/core/model/DataObject.php index c82b03367..9057640d6 100644 --- a/core/model/DataObject.php +++ b/core/model/DataObject.php @@ -650,9 +650,16 @@ class DataObject extends ViewableData implements DataObjectInterface { $fieldObj = $this->obj($fieldName); if(!isset($manipulation[$class])) $manipulation[$class] = array(); - // if database column doesn't correlate to a DBField instance, set up a default Varchar DBField - // (used mainly for has_one/has_many) - if(!$fieldObj) $fieldObj = DBField::create('Varchar', $this->record[$fieldName], $fieldName); + // if database column doesn't correlate to a DBField instance... + if(!$fieldObj) { + // Set up a default Int field for relations + if(preg_match('/ID$/', $fieldName) && $this->has_one(substr($fieldName,0,-2))) { + $fieldObj = DBField::create('Int', $this->record[$fieldName], $fieldName); + // Otherwise set up a default Varchar field + } else { + $fieldObj = DBField::create('Varchar', $this->record[$fieldName], $fieldName); + } + } // CompositeDBFields handle their own value storage; regular fields need to be // re-populated from the database diff --git a/tests/DataObjectTest.php b/tests/DataObjectTest.php index 1991d5e8c..9e2e5c97e 100644 --- a/tests/DataObjectTest.php +++ b/tests/DataObjectTest.php @@ -262,6 +262,32 @@ class DataObjectTest extends SapphireTest { $this->assertNotEquals($keysA, $keysB); } + + function testWriteSavesToHasOneRelations() { + /* DataObject::write() should save to a has_one relationship if you set a field called (relname)ID */ + $team = new DataObjectTest_Team(); + $captainID = $this->idFromFixture('DataObjectTest_Player', 'player1'); + $team->CaptainID = $captainID; + $team->write(); + $this->assertEquals($captainID, DB::query("SELECT CaptainID FROM DataObjectTest_Team WHERE ID = $team->ID")->value()); + + /* After giving it a value, you should also be able to set it back to null */ + $team->CaptainID = ''; + $team->write(); + $this->assertEquals(0, DB::query("SELECT CaptainID FROM DataObjectTest_Team WHERE ID = $team->ID")->value()); + + /* You should also be able to save a blank to it when it's first created */ + $team = new DataObjectTest_Team(); + $team->CaptainID = ''; + $team->write(); + $this->assertEquals(0, DB::query("SELECT CaptainID FROM DataObjectTest_Team WHERE ID = $team->ID")->value()); + + /* Ditto for existing records without a value */ + $existingTeam = $this->objFromFixture('DataObjectTest_Team', 'team1'); + $existingTeam->CaptainID = ''; + $existingTeam->write(); + $this->assertEquals(0, DB::query("SELECT CaptainID FROM DataObjectTest_Team WHERE ID = $existingTeam->ID")->value()); + } } class DataObjectTest_Player extends Member implements TestOnly { @@ -273,15 +299,19 @@ class DataObjectTest_Player extends Member implements TestOnly { } class DataObjectTest_Team extends DataObject implements TestOnly { - - static $db = array( - 'Title' => 'Text', - ); - - static $many_many = array( - 'Players' => 'DataObjectTest_Player' - ); - + + static $db = array( + 'Title' => 'Text', + ); + + static $has_one = array( + "Captain" => 'DataObjectTest_Player', + ); + + static $many_many = array( + 'Players' => 'DataObjectTest_Player' + ); + } ?> diff --git a/tests/SiteTreeTest.php b/tests/SiteTreeTest.php index 47070747a..a4773b4ae 100644 --- a/tests/SiteTreeTest.php +++ b/tests/SiteTreeTest.php @@ -104,6 +104,20 @@ class SiteTreeTest extends SapphireTest { $this->assertContains('Products', $allChildren); $this->assertNotContains('Staff', $allChildren); } + + function testCanSaveBlankToHasOneRelations() { + /* DataObject::write() should save to a has_one relationship if you set a field called (relname)ID */ + $page = new SiteTree(); + $parentID = $this->idFromFixture('Page', 'home'); + $page->ParentID = $parentID; + $page->write(); + $this->assertEquals($parentID, DB::query("SELECT ParentID FROM SiteTree WHERE ID = $page->ID")->value()); + + /* You should then be able to save a null/0/'' value to the relation */ + $page->ParentID = null; + $page->write(); + $this->assertEquals(0, DB::query("SELECT ParentID FROM SiteTree WHERE ID = $page->ID")->value()); + } }