Я изменил схему приложения Symfony, преобразовав отношение один ко многим в отношение многие ко многим между моделью Sample
и моделью Collector
. Модель Sample
имела внешний ключ collector_id
, и теперь есть промежуточная модель (SampleCollectors
) с двумя внешними ключами: sample_id
и collector_id
.
Sample:
columns:
id: { type: integer, primary: true, autoincrement: true }
...
collector_id: ... # This column is removed
...
relations:
...
Collectors: { foreignAlias: Collectors, class: Collector, local: sample_id, foreign: collector_id, refClass: SampleCollectors }
Collector:
columns:
id: { type: integer, primary: true, autoincrement: true }
...
relations:
Samples: { foreignAlias: Samples, class: Sample, local: collector_id, foreign: sample_id, refClass: SampleCollectors }
SampleCollectors:
columns:
sample_id: { type: integer, primary: true }
collector_id: { type: integer, primary: true }
relations:
Sample: { onDelete: cascade }
Я отредактировал schema.yml file
, как указано выше, и выполнил следующие задачи:
php symfony doc:generate-migrations-diff
php symfony doc:build --all-classes
, который перестроил каждую задействованную модель / форму / фильтр и создал два класса миграции.
Поскольку база данных уже находится в производственном режиме, я настроил классы миграции, чтобы переместить внешний ключ отношения «один ко многим» (Sample
. collector_id
) в промежуточную таблицу «многие ко многим». (SampleCollectors
collector_id
.):
public function preUp() {
$sampleTable = Doctrine_Core::getTable('Sample');
// I do this because collector_id has disappeared after model regeneration.
$sampleTable->setColumn('collector_id', 'integer', null, array('type' => 'integer'));
$this->samples = $sampleTable->findAll()->toArray();
}
public function up() {
// ...
$this->removeColumn('sample', 'collector_id');
// ...
$this->createTable('sample_collectors', array(...), array(
'type' => 'INNODB',
'primary' => array(0 => 'sample_id', 1 => 'collector_id'),
...));
}
public function postUp() {
foreach ( $this->samples as $sample ) {
$sampleCollector = new SampleCollectors();
$sampleCollector->setSampleId($sample['id']);
$sampleCollector->setCollectorId($sample['collector_id']);
$sampleCollector->trySave();
}
}
Я перенес базу данных и все прошло хорошо.
Но теперь, когда я обновляю контроллеры, представления и т. Д., Doctrine все еще пытается извлечь столбец collector_id
из образца, вместо того, чтобы перемещаться по соотношению «многие ко многим».
Поскольку модель Sample
больше не хранит ссылку на нее, почему Doctrine настаивает на этом? Я проверил класс BaseSample
, и у него нет метода hasColumn()
, устанавливающего столбец collector_id
. Кстати, я тоже очищаю кеш.
Спасибо!