Как самостоятельно инициализировать Doctrine_Record (как если бы Doctrine_Query) - PullRequest
0 голосов
/ 20 октября 2010

У меня есть модели, которые расширяют Doctrine_Record и напрямую отображаются на одну конкретную запись из базы данных (то есть одну запись с заданным id, статически закодированную в классе).

Теперь я хочу, чтобы конкретный класс записей инициализировался так, как если бы это делал Doctrine_Query. Итак, это будет нормальная процедура:

$query = new Doctrine_Query();
$model = $query->from('Model o')->where('id = ?', 123)->fetchOne();

Я бы хотел сделать что-то подобное

$model = new Model();

А в Model:

const ID = 123;

//note that __construct() is used by Doctrine_Record so we need construct() without the __
public function construct()
{
    $this->id = self::ID;
    //what here??
    $this->initialize('?????');
}

Итак, для ясности: я бы хотел, чтобы объект был точно таким же, как если бы он был получен из запроса (то же состояние, те же атрибуты, отношения и т. Д.).

Любая помощь будет принята с благодарностью: спасибо.

Ответы [ 3 ]

1 голос
/ 23 октября 2010

Хотя наличие нескольких классов для одного и того же типа данных (т.е. таблицы) на самом деле не то, чем должен быть ORM, то, что вы хотите, можно сделать в Doctrine, используя наследование агрегации столбцов. Предполагая, что вы используете Doctrine 1.2.x, вы можете написать следующее YML:

Vehicle:
  columns:
    brand: string(100)
    fuelType: string(100)

Car:
  inheritance:
    extends: Entity
    type: column_aggregation
    keyField: type
    keyValue: 1

Bicycle:
  inheritance:
    extends: Entity
    type: column_aggregation
    keyField: type
    keyValue: 2

Теперь таблица «Автомобиль» будет иметь столбец «тип», который определяет класс, который Doctrine будет создавать при выборе транспортного средства. У вас будет три класса: Автомобиль, Автомобиль и Велосипед. Вы можете назначить каждому классу свои собственные методы и т. Д., В то время как записи, которые представляют их экземпляры, находятся в одной таблице базы данных. Если вы используете $a = new Bicycle, Doctrine автоматически устанавливает тип для вас, поэтому вам не нужно об этом заботиться.

1 голос
/ 24 октября 2010

Первое, что мне нужно сказать , - это поместить константу в класс. Так вот так:

class Application_Model_Person
{
    const ID = 1234;
}

Затем метод Doctrine, такой как Doctrine_Record :: fetchOne (), всегда возвращает (новый) экземпляр модели и никогда не объединяет данные с записью, для которой вызывается fetchOne (). Тем не менее, Doctrine может объединить полученную запись с другим классом, поэтому сделать это довольно просто:

class Application_Model_Person extends Doctrine_Record_Abstract
{
    const ID = 1234;

    public function __construct($table = null, $isNewEntry = false)
    {
        // Calling Doctrine_Record::__construct
        parent::__construct($table, $isNewEntry);

        // Fetch the record from database with the id self::ID
        $record = $this->getTable()->fetchOne(self::ID);
        $this->merge($record);
    }
}

Тогда вы можете сделать:

$model = new Application_Model_Person;
echo $model->id; // 1234
0 голосов
/ 20 октября 2010

Я не думаю, что экземпляр модели мог бы решить повесить определенную запись базы данных после ее инициализации. Тем не менее, вы можете сделать что-то вроде этого:

<?php
class Model extends baseModel {
  public static function create($id = null)
  {
    if ($id === null) return new Model;
    return Doctrine::getTable('Model')->findeOneById($id);
  }
}

И затем, вы можете использовать

$newModel = Model::create();

Или получить существующий с идентификатором 14 (например), используя

$newModel = Model::create(14);

Или, если вы хотите, чтобы 123 был по умолчанию вместо нового элемента , объявите функцию следующим образом:

  public static function create($id = 123)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...