I've got a simple varchar product attribute, let's call it "badge".
If I set values for it programmatically for a set of products like this:
Mage::getModel('catalog/product_action')
->updateAttributes($productIds, ['badge' => 123, $store->getId());
... then I inspect the catalog_product_entity_varchar
table for that attribute value, I correctly see that 123 has been assigned to the badge attribute for those products, at the given store level. Great!
Now, if I create an EAV product collection by getting child products from a configurable and try and select the value, I can't:
$collection = $configurable->getTypeInstance(true)->getUsedProductCollection();
$collection->addAttributeToSelect('badge');
foreach ($collection as $product) { /** @var Mage_Catalog_Model_Product $product */
var_dump($product->getBadge()); // NULL
}
On closer inspection the varchar attribute values are assigned at the store level, but there's no default level value. If I manually insert a value at the global/admin level (doesn't matter what the value is), then the same code above works as it should.
Examining app/code/core/Mage/Catalog/Model/Resource/Collection/Abstract.php
I see that it selects attribute values from the default store level then does a left join to the specified store level to get the store value. It returns whichever exists from store -> default priority.
I understand that setting values via $product->setBadge(123)->save()
would also create a default value, but that's much slower, and not really the point of this question anyway.
FYI if I edit the abstract collection and switch the order around, i.e. select from the store level value and left join the default value it returns the value in my example code correctly - that was just to test the point, it's obviously not sustainable.
Question: This methodology obviously doesn't work due to a limitation in the core catalog collection. How can I efficiently set store level attribute values for large numbers of products (using vanilla Magento) while still being able to retrieve their values in a child product (EAV) collection?