Question

Today I came accross the issue of updating product's attribute programatically in observer on each visit on product page. As it should be really fast in that case I was wondering what is the best way to achieve that.

First of all one can get product model, set value on object using setter and save it using productRepository. But it is not fast, and it is really buggy on frontend.

Second option is using (I think) some methods from Magento/Catalog/Model/ResourceModel/AbstractResource and there two method that catch my eye here. First one is _updateAttribute($object, $attribute, $valueId, $value), but it is a bit unclear for me - $object is for sure product object which is binded with value to update, $value means exact value it should be after saving, but what exactly should I pass as $argument - instance of what class and do I really need to have id of field in db as $valueId?

Method _updateAttributeForStore($object, $attribute, $value, $storeId) seems more clear to me. Although I still have to have some object for $attribute, but I don't have to provide exact field id - so maybe I should use this one?

Of course both methods are protected, so I have to find some class that has access to these methods or create new class with wrappers for that ones.

Third way is to create direct query to db using some methods of classes directly communicating with db and mysql. I think although it shouldn't be used if possible for many reasons - for example safety of crud operations or breaking of model concept.

Was it helpful?

Solution

I have used method updateAttributes of class \Magento\Catalog\Model\ResourceModel\Product\Action. Method can update multiple products and attribute values, but if you want to update just one product with one attribute value you can do it like this:

$this->action->updateAttributes([$product->getId()], ['attribute_code' => $newValue], $storeId);

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top