Silverstripe добавить/сохранить объект в отношение has_one

Я не могу найти подсказку, как правильно сохранить отношение has_one в Silverstripe.

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...


person Asped    schedule 27.09.2013    source источник


Ответы (2)


кажется, нет дополнительного метода для добавления отношений has_one, но если вы хотите придерживаться ORM, вы можете сделать это наоборот:

$g->cars()->add($c);
person schellmax    schedule 27.09.2013
comment
спасибо, да, это правильный путь, хотя кажется немного странным назначать гараж машине, когда по логике было бы лучше поставить машину в гараж ;) - person Asped; 27.09.2013

Этот вопрос особенно актуален, если у вас нет соответствующей связи has_many, но вы хотите установить несохраненную связь между двумя объектами.

Что сработало для меня, так это создание свойства в исходном классе и назначение ему несохраненного связанного объекта. Основные ограничения:

  • Ваша ссылка на самый последний экземпляр объекта всегда должна быть свойством, иначе вы получите проблемы с параллелизмом.
  • Назначаемые большие объекты отягощают вашу доступную память.

К счастью, мой случай был очень простым объектом.

Пример:

Автомобиль.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;
}

. . .
person jakxnz    schedule 22.09.2016