I'm having trouble setting values to a multiselect type attribute for a product programatically.
Example attribute: material
Example values: cotton & polyester
Please note that both attribute and option values are created from the backend.
This is what I have tried so far:
$product = $objectManager->create('Magento\Catalog\Model\Product');
$sku = '1234';
$product_id = $product->getIdBySku($sku);
if ($product_id) {
$product->load($product_id);
$attribute_values = array('cotton','polyester');
$product_resource = $product->getResource();
$attribute_code = 'material';
$attribute = $product_resource->getAttribute($attribute_code);
if ($attribute->usesSource()) {
foreach ($attribute_values as $attribute_value) {
$attribute_option_ids[] = $attribute->getSource()->getOptionId($attribute_value);
}
$product->setData($attribute_code, $attribute_option_ids); // attempt 1
//$product->setData($attribute_code, array($attribute_option_ids)); // attempt 2
//$product->getResource()->saveAttribute($product, $attribute_code); // attempt 3 with combining attempt 1
}
$product->save();
}
The end result is that no values are set for the material attribute for product 1234.
Any ideas what I'm doing wrong?
2 Answers 2
Just to it like below code :
Inject this below class in your construct:
protected $productRepository;
public function __construct(
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository
) {
$this->productRepository = $productRepository;
}
And use this below code :
$product = $this->productRepository->getById('product-id');
$product->setData('attribute-code', 'attribute-value');
$this->productRepository->save($product);
Object Manager :
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->get('\Magento\Catalog\Model\ProductRepository')->getById('product-id');
$product->setData('attribute-code', 'attribute-value');
$this->productRepository->save($product);
-
Thank you for the answer. It seems like a good way to set product data, but I figured out what the issue was by myself. BTW, do you have any idea if using the product repository is possibly faster/better at updating attributes than going through the product model?Lez– Lez2020年10月02日 08:52:08 +00:00Commented Oct 2, 2020 at 8:52
-
Product repository used for rest API functionality also. So, it would be good if you use product repository. If it's useful you can accept answer :) Thanks.Rohan Hapani– Rohan Hapani2020年10月02日 08:53:53 +00:00Commented Oct 2, 2020 at 8:53
-
I would, but I haven't tested and verified that it works with your method so I can't accept it. Since I solved the issue on my own, I won't be testing this, but if someone verifies that this works for multiselect attributes, I will gladly accept it.Lez– Lez2020年10月02日 10:23:38 +00:00Commented Oct 2, 2020 at 10:23
It seems that my original code is working, but the problem was that I had 2 store views.
When setting attributes like this, it required an additional line of code:
$product->setStoreId(0); // store_id = 0 is the default store
Before saving the product.
The attributes were actually being saved for the main store view (my store has multiple store views), but the "default product data" (default view) remained unchanged.
The "attempt 1" from the code in my question was the correct way of setting this data.
Explore related questions
See similar questions with these tags.
setCustomAttributeinstead ofsetDataand for some reason sometimes it was working while other times not..