在Magento中如何在不保存父实体的情况下保存属性值

8
我希望能够保存属性值而不保存其父实体。 我通过我的模块的sql/setup文件创建了一个新的客户属性(参考),现在我想为每个现有客户填充该属性。我已经为该属性创建了后端模型,可以在实体加载(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;
}
}

理想情况下,我希望在 afterLoad 方法中调用类似于 $this->getAttribute()->setValue('blah')->save() 的内容,以便不必依赖用户点击保存按钮。
我可以编写一个脚本来加载所有客户的集合并设置该值,但是由于有超过50,000个客户,我担心在生产服务器上运行它会对性能产生影响...
有任何想法感激不尽。
JD
3个回答

19

EAV资源模型提供了保存单个属性而不保存实体的能力。

$value = Mage::helper('referral')->generateRafCode($oCustomer);
$oCustomer->setData($vAttrCode, $value)->getResource()->saveAttribute($oCustomer, $vAttrCode);

太好了!我喜欢它,现在把它放在我的笔记里。 - dan.codes
@dan.codes 你有记笔记吗?我以为这就是 StackOverflow 的全部意义...你会发现我重新回到这个问题的原因是因为我需要再次使用它,而且没有笔记! :) - Jonathan Day
@JonathanDay 哈哈,是的,这是一些笔记和 Stack Overflow 收藏夹,以及过去项目的代码片段集合。 - dan.codes
2
我想补充一下,对于具有“静态”后端类型的属性是不可能的!您将收到一个错误消息:“在字段列表中未知列'customer_entity.value_id'”。 - Michael Leiss
@vinai,我能否使用这种方法将EAV属性保存到特定的商店范围? - zainengineer
对于存储作用域变量,Mage::getSingleton('catalog/product_action')->updateAttributes(...) 看起来以类似的方式工作。 - zainengineer

2

因此,一个有效的选项是直接向数据库写入。虽然这并不特别优雅,但在实现“懒加载”方法以为现有客户(或其他实体)填充新属性方面非常有效。以下是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模型上公开一个获取Write Adapter的公共方法,但这不是什么大问题。

我仍然很想知道是否有一种更好地使用EAV模型层的方法...


0
Vinai提供的解决方案对于后端类型为静态的属性无效。在静态情况下,您只能像这样做:
        $adapter = Mage::getSingleton('core/resource')->getConnection('core_write');
        $adapter->update(
            "customer_entity",
            array("group_id" => $customerGroupId),
            "entity_id=$customerId"
        );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接