Używanie ORM Magento do wstawienia określonego pola identyfikatora

14

Czy istnieje sposób użycia prostego ORM Magento ( Mage_Core_Model_Abstracti Mage_Core_Model_Resource_Abstract) do wstawienia wierszy modelu za pomocą określonego klucza głównego?

Na przykład, jeśli uruchomiłem poniższe polecenie na pustym systemie 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,
)); 

Spodziewałbym się nowego wpisu w core_websitetabeli. Jednak Magento po cichu nic tu nie robi.

Zagłębiając się w zasób, wygląda na to, że popadam w błąd w klasie zasobów bazy danych

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

Ponieważ model ma identyfikator (tzn. Wstawiam konkretny identyfikator), a ponieważ _useIsObjectNewjest zakodowany na fałsz, moje żądanie zapisu jest zawsze kierowane do insertścieżki.

Czy istnieje sposób, aby wymusić wstawienie przy użyciu domyślnych modeli Magento? (bez przepisywania / zastępowania klas).

Tak, surowy SQL jest opcją, ale wtedy funkcjonalność zdarzenia zostaje utracona.

Alan Storm
źródło
Dlaczego próbujesz przypisać identyfikator do pola autorekreacji? Jeśli jest to zależność niższego szczebla, czy nie należy po prostu utworzyć rekord, a następnie pobrać automatycznie wygenerowany PK?
Ralph Tice
@RalphTice Tak, to prawdopodobnie byłaby dobra rzecz do codziennego użytku.
Alan Storm

Odpowiedzi:

5

Więc tak. ( edycja :) Sztuczka polega na użyciu Mage_Core_Model_Abstractpodklasy, która nie ma pola identyfikatora oczekiwanego przez model zasobów:

$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', [...])to tylko wydarzenie, które widzę, że jest konsumowane w rdzeniu Może to być tak proste, jak wykonanie

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

W każdym razie potrzebuję prysznica.

zalety
źródło
1
Gdy już będziesz czysty - nie jestem pewien, czy to zrobię - w forsedSave gist.github.com/astorm/5219357 jest podobny identyfikator . Czy to zadziałało dla ciebie, czy była to tylko teoria?
Alan Storm
Zredagowałem moją odpowiedź, aby była bardziej oczywista.
zaznacza
... i zadziałało dla mnie.
zyskuje
Ach, właśnie to dostaję za pisanie własnego kodu zamiast kopiowania i wklejania. Używając tego jako punktu wyjścia, czy widzisz jakiś powód, aby nie używać Varien_Objectzamiast innej klasy modelu, a następnie wywołujesz savemetodę amortyzacji zasobu ?
Alan Storm
Odpowiadając na moje pytanie powyżej, to dlatego, że metoda zapisu zasobu ogólnego ma Mage_Core_Model_Abstractpodpowiedzi typu dla tablicy danych.
Alan Storm