У меня есть небольшая проблема со многими и многими отношениями в одной таблице с использованием Symfony 1.4 с Propel ORM. Моя schema.yml выглядит следующим образом:Отношение многих ко многим к одной таблице
propel:
item:
_attributes: { phpName: Item }
id: { phpName: Id, type: INTEGER, size: '10', primaryKey: true, autoIncrement: true, required: true }
type_id: { phpName: TypeId, type: INTEGER, size: '11', required: true, foreignTable: type, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
owner_id: { phpName: OwnerId, type: INTEGER, size: '11', required: true, foreignTable: owner, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
place_id: { phpName: PlaceId, type: INTEGER, size: '11', required: true, foreignTable: place, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
picture_id: { phpName: PictureId, type: INTEGER, size: '11', required: false, foreignTable: picture, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
supplier_id: { phpName: SupplierId, type: INTEGER, size: '11', required: false, foreignTable: supplier, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
name: { phpName: Name, type: VARCHAR, size: '255', required: true }
amount: { phpName: Amount, type: INTEGER, size: '11', required: true }
wished_amount: { phpName: WishedAmount, type: INTEGER, size: '11', required: true }
costs: { phpName: Costs, type: DECIMAL, size: '7', scale: '2', required: true }
description: { phpName: Description, type: LONGVARCHAR, required: false }
use_until: { phpName: UseUntil, type: DATE, required: false }
last_used: { phpName: LastUsed, type: TIMESTAMP, required: false }
last_updated: { phpName: LastUpdated, type: TIMESTAMP, required: false }
_indexes: { item_FI_1: [type_id], item_FI_2: [owner_id], item_FI_3: [place_id], item_FI_4: [picture_id], item_FI_5: [supplier_id] }
item_has_item:
item_id: { type: INTEGER, required: true, foreignTable: item, foreignAlias: item, foreignReference: id, primaryKey: true}
parent_item_id: { type: INTEGER, required: true, foreignTable: item, foreignAlias: parent_item, foreignReference: id, primaryKey: true}
_indexes: { item_has_item_FKIndex1: [item_id], item_has_item_FKIndex2: [parent_item_id] }
Однако в генераторе админки необходимое admin_double_list
не появляется автоматически. Это происходит, когда второй foreignTable
настроен на другую таблицу, например sf_guard_user
. Я читал, что это может быть исправлено в Propel 1.3, но я не знаю, какая версия Propel включена в Symfony 1.4.
Надеюсь, я дал достаточно информации для решения моей проблемы, ребята, ребята. В противном случае мне придется сделать еще одну таблицу, которая хранит элементы, которые имеют дочерний элемент, например:
< Предмет ---- Item_has_item < ---- Combined_item
EDIT ПОСЛЕ РЕАКЦИИ ОТ j0k
После реакции с j0k я обновил sfPropelORMPlugin, и он действительно распознал отношение. Тем не менее, я до сих пор есть ошибка при сохранении (только тогда, когда отношение сделан):
Unable to execute INSERT statement [INSERT INTO `item_has_item` (`ITEM_ID`) VALUES (:p0)]
[wrapped: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a
child row: a foreign key constraint fails (`SI/item_has_item`, CONSTRAINT
`item_has_item_FK_1` FOREIGN KEY (`parent_item_id`) REFERENCES `item` (`id`))]
Я обнаружил, после долгого тщательного поиска, что форма генератор не сможет правильно понять многие-ко-многим по той же таблице. В функции saveItemHasItemList ($ CON = нуль):
$c = new Criteria();
$c->add(ItemHasItemPeer::ITEM_ID, $this->object->getPrimaryKey());
ItemHasItemPeer::doDelete($c, $con);
$values = $this->getValue('item_has_item_list');
if (is_array($values))
{
foreach ($values as $value)
{
$obj = new ItemHasItem();
$obj->setItemId($this->object->getPrimaryKey());
$obj->setItemId($value);
$obj->save();
}
}
Как вы можете видеть, ItemId дважды установлен, в то время как ParentItemId не установлен, следовательно, значение ограничения. Он должен быть создан как:
$c->add(ItemHasItemPeer::ITEM_ID, $this->object->getPrimaryKey());
$c->add(ItemHasItemPeer::PARENT_ITEM_ID, $this->object->getPrimaryKey());
& &
$obj->setParentItemId($this->object->getPrimaryKey());
$obj->setItemId($value);
Это решает проблему экономии, однако, он все еще не показывает уже выбранные отношения. Для того, чтобы решить, что вы должны также изменить updateDefaultsFromObject():
foreach ($this->object->getItemHasItemsRelatedByItemId() as $obj)
Должно быть:
foreach ($this->object->getItemHasItemsRelatedByParentItemId() as $obj)
Помните, что эти функции находятся в форме/базы/BaseItemForm.class.php, но функции должен быть перезаписан в /form/ItemForm.class.php.
Я считаю, что это ошибка Propel, поэтому я отправлю ее завтра на Propel TRAC.
Лучшая ошибка отчета на [Github] (https://github.com/propelorm/Propel). – j0k
Соответствующий билет GitHub: [Ticket] (https://github.com/propelorm/sfPropelORMPlugin/issues/143) –