Использование 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();

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


1
Как только вы очиститесь - я не уверен, что буду следовать этому - есть аналогичная проверка идентификатора в forsedSave gist.github.com/astorm/5219357 . Это сработало для вас, или это была просто теория?
Алан Сторм

Отредактировал мой ответ, чтобы сделать его более очевидным.
отметки

... и это сработало для меня.
отметки

Ах, вот что я получаю за то, что набираю свой собственный код вместо копирования и вставки. Используя это в качестве отправной точки, можете ли вы увидеть какую-либо причину не использовать Varien_Objectвместо другого класса модели, а затем вызывать метод, который не является устаревшим save?
Алан Шторм

И отвечая на мой собственный вопрос выше, это потому, что метод сохранения универсального ресурса имеет Mage_Core_Model_Abstractподсказку типа для массива данных.
Алан Шторм
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.