Использование ORM Magento для вставки определенного поля идентификатора

14

Есть ли способ использовать простой ORM ( Mage_Core_Model_Abstractи Mage_Core_Model_Resource_Abstract) Magento для вставки строк модели с определенным первичным ключом?

Например, если я запустил следующее против пустой системы Magento

Mage::getModel('core/website')->setData(array (
    'website_id' => 2,
    'code' => 'foo',
    'name' => 'Main Website',
    'sort_order' => 0,
    'default_group_id' => 1,
    'is_default' => 1,
)); 

Я ожидаю новую запись в core_websiteтаблице. Тем не менее, Magento молча ничего не делает здесь.

Копаясь в ресурсе, похоже, что я не согласен с этим в классе ресурсов базы данных

#File: app/code/core/Mage/Core/Model/Resource/Db/Abstract.php
if (!is_null($object->getId()) && (!$this->_useIsObjectNew || !$object->isObjectNew())) {
    //update stuff here
}
else
{
    //insert stuff here
}

Поскольку модель имеет идентификатор (т. Е. Я вставляю конкретный идентификатор), и поскольку _useIsObjectNewона жестко запрограммирована на false, мой запрос на сохранение всегда направляется в insertпуть.

Есть ли способ принудительной вставки с моделями по умолчанию Magento? (без переписывания / замены класса).

Да, необработанный SQL - вариант, но тогда функциональность событий теряется.

Алан Сторм
источник
Почему вы пытаетесь присвоить идентификатор для поля автоинкремента? Если это нисходящая зависимость, разве вы не должны просто создать запись и затем извлечь автоматически сгенерированный PK?
Ральф Тис
@RalphTice Да, это, вероятно, будет правильным решением для повседневного использования.
Алан Шторм

Ответы:

5

Так что да. ( edit :) Хитрость заключается в использовании Mage_Core_Model_Abstractподкласса, который не имеет поля id, которого ожидает модель ресурса:

$evil = Mage::getModel('core/store'); // that's a store object, baby!
$evil->setData(
    array (
        'website_id' => 99,
        'code' => 'foo',
        'name' => 'Main Website9',
        'sort_order' => 0,
        'default_group_id' => 1,
        'is_default' => 1,
    )
);

Mage::getResourceModel('core/website')->forsedSave($evil);

Mage::dispatchEvent('website_save_commit_after', [...])это единственное событие, которое я вижу в ядре. Это может быть так же просто, как следовать с

Mage::getModel('core/website')->setData($evil->getData())->afterCommitCallback();

В любом случае мне нужен душ.

benmarks
источник
1
Как только вы очиститесь - я не уверен, что буду следовать этому - есть аналогичная проверка идентификатора в forsedSave gist.github.com/astorm/5219357 . Это сработало для вас, или это была просто теория?
Алан Сторм
Отредактировал мой ответ, чтобы сделать его более очевидным.
отметки
... и это сработало для меня.
отметки
Ах, вот что я получаю за то, что набираю свой собственный код вместо копирования и вставки. Используя это в качестве отправной точки, можете ли вы увидеть какую-либо причину не использовать Varien_Objectвместо другого класса модели, а затем вызывать метод, который не является устаревшим save?
Алан Шторм
И отвечая на мой собственный вопрос выше, это потому, что метод сохранения универсального ресурса имеет Mage_Core_Model_Abstractподсказку типа для массива данных.
Алан Шторм