Usando o ORM do Magento para inserir um campo de ID específico

14

Existe uma maneira de usar o ORM simples do Magento ( Mage_Core_Model_Abstracte Mage_Core_Model_Resource_Abstract) para inserir linhas de modelo com uma chave primária específica?

Por exemplo, se eu executasse o seguinte em um sistema Magento vazio

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

Eu esperaria uma nova entrada na core_websitetabela. No entanto, Magento silenciosamente não faz nada aqui.

Ao pesquisar no recurso, parece que estou entrando em conflito com isso na classe de recursos do banco de dados

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

Como o modelo possui um ID (ou seja, estou inserindo um ID específico) e como _useIsObjectNewé codificado como falso, minha solicitação de salvamento é sempre roteada para o insertcaminho.

Existe uma maneira de forçar uma inserção com os modelos padrão do Magento? (sem reescrever / substituir classe).

Sim, o SQL bruto é uma opção, mas a funcionalidade do evento é perdida.

Alan Storm
fonte
Por que você está tentando atribuir um ID a um campo de incremento automático? Se essa é uma dependência downstream, você não deve simplesmente criar o registro e recuperar a PK gerada automaticamente?
Ralph Tice
@ RalphTice Sim, isso provavelmente seria a coisa certa a ser usada no dia a dia.
Alan Storm

Respostas:

5

Então sim. ( edit :) O truque é usar uma Mage_Core_Model_Abstractsubclasse que não possui o campo id que o gabarito de recursos 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', [...])é o único evento que vejo sendo consumido no núcleo. Pode ser tão simples quanto seguir com

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

De qualquer forma, preciso de um banho.

benmarks
fonte
1
Quando você estiver limpo - não sei se segui-lo -, há uma verificação de identificação semelhante em forsedSave gist.github.com/astorm/5219357 . Isso funcionou para você ou foi apenas uma teoria?
Alan Storm
Editou minha resposta para torná-la mais óbvia.
22713 benmarks
... e funcionou para mim.
benmarks
Ah, é o que recebo por digitar meu próprio código em vez de copiar e colar. Usando isso como ponto de partida, você vê algum motivo para não usar uma Varien_Objectclasse de modelo diferente da classe diferente e depois chamar o savemétodo não depreciado do recurso ?
Alan Storm
E respondendo minha própria pergunta acima, é porque o método de salvamento do recurso genérico tem Mage_Core_Model_Abstractdicas de tipo para a matriz de dados.
Alan Storm