2013-09-27 31 views
2

我無法找到關於如何在Silverstripe中正確保存has_one關係的線索。Silverstripe添加/保存對象到has_one關係

class Car extends DataObject { 
    $has_one = array(
    'garage'=>'Garage'; 
); 
} 

class Garage extends DataObject { 
    $has_many = array(
    'cars'=>'Car'; 
); 
} 
// let's say I have these records in the DB 
$g = Garage::get()->ByID(111); 
$c = Car::get()->ByID(222); 

// I want to do sth like this to define the relation 
$c->Garage = $g; 
$c->write(); 

但是,這段代碼什麼也沒做,沒有錯誤,但也沒有在數據庫中創建關係。

了我所能做的是:

$c->GarageID = $g->ID; 
$c->write(); 

但這似乎不是很喜歡ORM ...

回答

3

似乎有不被添加HAS_ONE關係一個額外的方法,但如果要堅持使用ORM,你可以做它周圍的其他方法:

$g->cars()->add($c); 
+0

感謝,是的,這是正確的方式,儘管它看起來有點怪異「分配」車庫的汽車,當邏輯上這將是最好把車開進車庫;) – Asped

0

這個問題,如果你有沒有相應的has_many關係,而是要建立尤爲重要兩個對象之間未保存的關係。

對我而言,有效的方法是在初始類下創建一個屬性,並根據該屬性分配未保存的相關對象。主要限制是:

  • 您引用該對象的最新實例需要始終是該屬性,否則您會遇到一致性問題。
  • 正在設計的大型物體會降低可用內存。

幸運的是,我的情況是一個非常簡單的對象。

例子:

Car.php:

. . . 

private static $has_one = array(
    'Garage' => 'Garage' 
); 

private $unsaved_relation_garage; 

protected function onBeforeWrite() { 

    parent::onBeforeWrite(); 

    // Save the unsaved relation too 
    $garage = $this->unsaved_relation_garage; 

    // Check for unsaved relation 
    // NOTE: Unsaved relation will override existing 
    if($garage) { 

     // Check if garage already exists in db 
     if(!$garage->exists()) { 

      // If not, write garage 
      $garage->write(); 
     } 

     $this->GarageID = $garage->ID; 
    } 
} 

/** 
* setGarage() will assign a written garage to this object's has_one 'Garage', 
* or an unwritten garage to $this->unsaved_relation_garage. Will not write. 
* 
* @param Garage $garage 
* @return Car 
*/ 
public function setGarage($garage) { 

    if($garage->exists()) { 
     $this->GarageID = $garage->ID; 
     return $this; 
    } 

    $this->unsaved_relation_garage = $garage; 
    return $this; 
} 

/** 
* getGarage() takes advantage of the variation in method names for has_one relationships, 
* and will return $this->unsaved_relation_garage or $this->Garage() dependingly. 
* 
* @return Garage 
*/ 
public function getGarage() { 

    $unsaved = $this->unsaved_relation_garage; 

    if($unsaved) { 
     return $unsaved; 
    } 

    if($this->Garage()->exists()) { 
     return $this->Garage(); 
    } 

    return null; 
} 

. . .