сохранить значение атрибута без сохранения его родительского объекта в Magento - PullRequest
8 голосов
/ 16 июля 2011

Я хотел бы иметь возможность сохранить значение атрибута без сохранения его родительской сущности.Я создал новый атрибут customer через файл sql / setup моего модуля ( ref ), и теперь я хочу заполнить этот атрибут для каждого из существующих клиентов.Я создал Backend-модель для атрибута, который обнаруживает нулевые значения во время загрузки объекта (afterLoad) и генерирует содержимое, но я не решаюсь сохранить объект в этой точке процесса.

class Aligent_Referral_Model_Customer_Attribute_Backend_Referralcode extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract
{
public function afterLoad($oCustomer)
{
    $vAttrCode = $this->getAttribute()->getAttributeCode();
    $vValue = $oCustomer->getData($vAttrCode);
    if (empty($vValue)){
        $oCustomer->setData($vAttrCode, Mage::helper('referral')->generateRafCode($oCustomer));
    }
    return $this;
}
}

В идеале я хотел бы вызвать что-то вроде $this->getAttribute()->setValue('blah')->save() в этом методе afterLoad, чтобы он не зависел от нажатия кнопки «Сохранить».

Я мог бы написать сценарий, который загружает коллекцию всех клиентов и проверяет их, чтобы установить значение, но есть более 50 000 клиентов, и я обеспокоен влиянием производительности на выполнение этого на производственном сервере ...

Любые мысли приветствуются.
JD

Ответы [ 3 ]

19 голосов
/ 17 ноября 2011

Модель ресурсов EAV предлагает возможность сохранения отдельных атрибутов без сохранения сущности.

$value = Mage::helper('referral')->generateRafCode($oCustomer);
$oCustomer->setData($vAttrCode, $value)->getResource()->saveAttribute($oCustomer, $vAttrCode);
2 голосов
/ 17 июля 2011

Так что один вариант, который работает, это писать напрямую в базу данных.Это не особенно элегантно, но довольно эффективно для достижения подхода «ленивой нагрузки» для заполнения нового атрибута для существующих клиентов (или других объектов).Вот дополнительный код в Attribute_Backend_Referralcode к тому, что я опубликовал в вопросе:

$vAttrValue = 'some string';
$oCustomer->setData($vAttrCode, $vAttrValue);
$iAttrId = $this->getAttribute()->getAttributeId();
$data = array(
            'entity_type_id' => $oCustomer->getEntityTypeId(),
            'attribute_id' => $iAttrId,
            'entity_id' => $oCustomer->getId(),
            'value' => $vAttrValue,
        );
$vTableName = $this->getAttribute()->getBackend()->getTable();
Mage::getResourceModel('table/alias')->getWriteAdapter()->insert($vTableName, $data);

Требуется использование открытого метода для получения адаптера записи в модели Mysql4, но в этом нет ничего сложного.

Еще интересно узнать, есть ли подход, который лучше использует слой модели EAV ...

0 голосов
/ 23 марта 2018

Решение, предоставленное Vinai, не работает для атрибутов со статическим типом внутреннего интерфейса.В случае статического вы можете сделать только что-то вроде этого:

        $adapter = Mage::getSingleton('core/resource')->getConnection('core_write');
        $adapter->update(
            "customer_entity",
            array("group_id" => $customerGroupId),
            "entity_id=$customerId"
        );
...