How to save only specific attribute value rather than saving the whole product in Magento2
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.
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;
}
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);