11

As you guys already know that we used to have this below method in magento to save a specific attribute value like this.

// saving product attribute
$product = Mage::getModel('catalog/product')->load('id here');
$product->setName('your name here');
$product->getResource()->saveAttribute($product, 'name');

or

// saving customer attribute
$customer->setData($attrCode, $value)->getResource()->saveAttribute($customer, $attrCode);

Can anyone let me know the alternative of the above in Magento2 .

4 Answers 4

11

Its the same as Magento 1

$dataobject->setData('attribute_code', $value);
$dataobject->getResource()->saveAttribute($dataobject, 'attribute_code');

This will work for any entity.

As per @Raphael's Answer It will not work for sales attributes.

Basically it calls Magento\Eav\Model\Entity\AbstractEntity::saveAttribute() function.

This will accept two parameters

saveAttribute(\Magento\Framework\DataObject $object, $attributeCode)

First to be $object is an object which needs to be updated and second parameter will be $attributeCode which is the code for the attribute to be updated.

5
  • It should be basically for any entity. Apr 12, 2017 at 11:06
  • Yes it will work for any entity. It will basically call Magento\Eav\Model\Entity\AbstractEntity::saveAttribute() which will accept a dataobject and entity code. Apr 12, 2017 at 11:11
  • Upvoting it but not accepting as an answer right now. I will check and update. Apr 12, 2017 at 11:29
  • Please go to line 1608 in the file. (Magento 2.1.5) there is another function public function saveAttribute(\Magento\Framework\DataObject $object, $attributeCode) Apr 12, 2017 at 11:40
  • 1
    Seems magento has basically kept all important functions intact. Apr 12, 2017 at 11:42
5

Just to clarify Jaimin's answer:

This will work for any entity.

This is not true. It will only work for EAV entities which extend Magento\Eav\Model\Entity\AbstractEntity

If you're dealing with a non EAV entity where the resource model extends Magento\Framework\Model\ResourceModel\Db\AbstractDb you will have to implement the saveAttribute method in your resource model.

In Magento 2, they have done it for the Magento\Sales\Model\ResourceModel\Attribute class:

public function saveAttribute(AbstractModel $object, $attribute)
{
    if ($attribute instanceof AbstractAttribute) {
        $attributes = $attribute->getAttributeCode();
    } elseif (is_string($attribute)) {
        $attributes = [$attribute];
    } else {
        $attributes = $attribute;
    }
    if (is_array($attributes) && !empty($attributes)) {
        $this->getConnection()->beginTransaction();
        $data = array_intersect_key($object->getData(), array_flip($attributes));
        try {
            $this->_beforeSaveAttribute($object, $attributes);
            if ($object->getId() && !empty($data)) {
                $this->getConnection()->update(
                    $object->getResource()->getMainTable(),
                    $data,
                    [$object->getResource()->getIdFieldName() . '= ?' => (int)$object->getId()]
                );
                $object->addData($data);
            }
            $this->_afterSaveAttribute($object, $attributes);
            $this->getConnection()->commit();
        } catch (\Exception $e) {
            $this->getConnection()->rollBack();
            throw $e;
        }
    }
    return $this;
}
0
4

In the case of product, you can use the mass action object. For example:

// Edit
$productIds = [123];
$attributesData = ['name' => 'new product name'];
$storeId = 0;
$productMassAction = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Catalog\Model\Product\Action');
$productMassAction->updateAttributes($productIds, $attributesData, $storeId);
0

You can save a product attribute value based on product id without saving the whole product itself. This saves a lot of time, especially when you have to update a bunch of products.

<?php

namespace Company\Module\Model;

use Magento\Catalog\Model\Product\Action;

class SomeClass
{
    /**
     * @var Action
     */
    private Action $productAction;

    /**
     * @param Action $productAction
     */
    public function __construct(
        Action $productAction
    ) {
        $this->productAction = $productAction;
    }

    public function someFunction($product)
    {
        $productIds = [$product->getId()]; // Array with one or more product ids
        $attributeUpdates = ['attribute_code' => 'value']; // Array with one or more attribute updates
        $storeId = \Magento\Store\Model\Store::DEFAULT_STORE_ID; // Scope id

        $this->productAction->updateAttributes(
            $productIds,
            $attributeUpdates,
            $storeId
        );
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.