Verwenden von Magentos ORM zum Einfügen eines bestimmten ID-Felds

14

Gibt es eine Möglichkeit, mit Magentos einfachem ORM ( Mage_Core_Model_Abstractund Mage_Core_Model_Resource_Abstract) Modellzeilen mit einem bestimmten Primärschlüssel einzufügen?

Zum Beispiel, wenn ich folgendes gegen ein leeres Magento-System ausgeführt habe

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

Ich würde einen neuen Eintrag in der core_websiteTabelle erwarten . Magento tut hier jedoch nichts.

Es sieht so aus, als würde ich in der Datenbank-Ressourcenklasse in die Quere kommen

#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
}

Da das Modell eine ID hat (dh, ich gebe eine bestimmte ID ein) und _useIsObjectNewfest auf false codiert ist, wird meine Speicheranforderung immer an den insertPfad weitergeleitet.

Gibt es eine Möglichkeit, eine Einfügung mit den Standard-Magento-Modellen zu erzwingen? (ohne ein Umschreiben / Klassenersatz).

Ja, Raw SQL ist eine Option, aber dann geht die Ereignisfunktionalität verloren.

Alan Storm
quelle
Warum versuchen Sie, einem Autoincrement-Feld eine ID zuzuweisen? Wenn dies eine nachgelagerte Abhängigkeit ist, sollten Sie dann nicht einfach den Datensatz erstellen und die automatisch generierte PK abrufen?
Ralph Tice
@RalphTice Ja, das wäre wahrscheinlich das Richtige für den täglichen Gebrauch.
Alan Storm

Antworten:

5

Also ja. ( edit:) Der Trick besteht darin, eine Mage_Core_Model_AbstractUnterklasse zu verwenden, die nicht das ID-Feld hat, das das Ressourcenmodell erwartet:

$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', [...])Dies ist das einzige Ereignis, bei dem ich sehe, dass es im Kern verbraucht wird. Es könnte so einfach sein, wie mit zu folgen

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

Auf jeden Fall brauche ich eine Dusche.

benmarks
quelle
1
Sobald Sie sauber sind - ich bin mir nicht sicher, ob ich dem folge - gibt es einen ähnlichen ID-Check unter forsedSave gist.github.com/astorm/5219357 . Hat das für Sie funktioniert oder war es nur eine Theorie?
Alan Storm
Bearbeitet meine Antwort, um es offensichtlicher zu machen.
Benmarks
... und es hat bei mir funktioniert.
benmarks
Ah ha, das ist es, was ich bekomme, um meinen eigenen Code zu tippen, anstatt ihn zu kopieren und einzufügen. Können Sie als Ausgangspunkt einen Grund sehen, nicht Varien_Objectstatt der anderen Modellklasse eine zu verwenden und dann die nicht abgeschriebene saveMethode der Ressource aufzurufen ?
Alan Storm
Und meine eigene Frage oben zu beantworten, liegt daran, dass die Speichermethode der generischen Ressource einen Mage_Core_Model_AbstractTipp für das Datenarray enthält.
Alan Storm