Usando el ORM de Magento para insertar un campo de identificación específico

14

¿Hay alguna manera de usar el ORM simple de Magento ( Mage_Core_Model_Abstracty Mage_Core_Model_Resource_Abstract) para insertar filas de modelo con una clave primaria específica?

Por ejemplo, si ejecuté lo siguiente contra un sistema Magento vacío

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

Esperaría una nueva entrada en la core_websitetabla. Sin embargo, Magento silenciosamente no hace nada aquí.

Excavando en el recurso, parece que estoy cayendo en conflicto con esto en la clase de recurso de base de datos

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

Debido a que el modelo tiene una identificación (es decir, estoy insertando una identificación específica), y debido a que _useIsObjectNewestá codificado como falso, mi solicitud de guardar siempre se enruta a la insertruta.

¿Hay alguna forma de forzar una inserción con los modelos Magento predeterminados? (sin una reescritura / reemplazo de clase).

Sí, el SQL sin formato es una opción, pero luego se pierde la funcionalidad del evento.

Alan Storm
fuente
¿Por qué está tratando de asignar una identificación a un campo de incremento automático? Si se trata de una dependencia posterior, ¿no debería simplemente crear el registro y luego recuperar la PK autogenerada?
Ralph Tice
@RalphTice Sí, eso probablemente sería lo correcto para el uso diario.
Alan Storm

Respuestas:

5

Así que sí. ( editar :) El truco consiste en utilizar una Mage_Core_Model_Abstractsubclase que no tenga el campo id que el modelo de recurso espera:

$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', [...])es el único evento que veo que se consume en el núcleo Podría ser tan simple como seguir con

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

En cualquier caso, necesito una ducha.

puntos de referencia
fuente
1
Una vez que esté limpio, no estoy seguro de seguirlo, hay una verificación de identificación similar en forsedSave gist.github.com/astorm/5219357 . ¿Funcionó esto para usted o fue solo una teoría?
Alan Storm
Edité mi respuesta para hacerlo más obvio.
puntos de referencia
... y funcionó para mí.
puntos de referencia
Ah, ja, eso es lo que obtengo por escribir mi propio código en lugar de copiar y pegar. Usando esto como punto de partida, ¿puede ver alguna razón para no usar una Varien_Objectclase de modelo en lugar de otra diferente y luego llamar al savemétodo no depreciado del recurso ?
Alan Storm
Y respondiendo mi propia pregunta anterior, es porque el método de guardado del recurso genérico tiene Mage_Core_Model_Abstractsugerencias de tipo para la matriz de datos.
Alan Storm