Magento – Update EAV attribute value in custom admin module

attributesbugcustom-attributeseavmodel

I have a form container with save button . This is the method that the save button call.

public function saveAction(){
    $userId = Mage::getSingleton('admin/session')->getUser()->getId();
    $user = Mage::getModel('admin/user')->load($userId);
    $idSetting=$user->getShopsetting_entity_id();
    $setting=Mage::getSingleton('Name_Module/shopSetting')->load($idSetting);

    $setting->setData($this->getRequest()->getParam('shopSetting'));
    $setting->save();

    return $this->_redirect('*/*/index');
}

This method create another element in shopSetting_entity, but I want the attributes value is modified.

I also try using

$setting->setAttributeName($shopSetting['attribute_name']);
$setting->save();

But in this case Magento add a row in shopSetting_entity_int with same entity_type_id,attribute_id,store_id,entity_id and does not modify the old one.

(int is the type of attribute_name)

I also try with

$setting->setAttributeName($shopSetting['attribute_name']);
$setting->getResource()->saveAttribute($setting,'attribute_name');

But the result is always the same.

In particular case of the method saveAttribute of Mage_Eav_Model_Entity_Abstract I note that this method distinguishes between the update and insertion, this is the code:

....
 $select = $adapter->select()
                ->from($table, 'value_id')
                ->where($where);
            $origValueId = $adapter->fetchOne($select);

            if ($origValueId === false && ($newValue !== null)) {
                $this->_insertAttribute($object, $attribute, $newValue);
            } elseif ($origValueId !== false && ($newValue !== null)) {
                $this->_updateAttribute($object, $attribute, $origValueId, $newValue);
            } elseif ($origValueId !== false && ($newValue === null)) {
                $adapter->delete($table, $where);
            }
            $this->_processAttributeValues();
            $adapter->commit();
...

but _insertAttribute and _updateAttribute call the same method _saveAttribute

    protected function _insertAttribute($object, $attribute, $value)
{
    return $this->_saveAttribute($object, $attribute, $value);
}

….

    protected function _updateAttribute($object, $attribute, $valueId, $value)
{
    return $this->_saveAttribute($object, $attribute, $value);
}

maybe there's a bug

Best Answer

If you call setData() with an array, the complete data gets replaced, this includes the ID.

So, if the result of $this->getRequest()->getParam('shopSetting') does not contain the ID, a new entity is created.

You probably are looking for addData() which sets only the attributes that exist in the passed array and leaves the rest as it is.