Сериализуемые поля в коллекциях Magento
-
16-10-2019 - |
Вопрос
В моей модели ресурса я определил поле как сериализуемое (см. Свойство $_serializableFields
в Mage_Core_Model_Resource_Db_Abstract
): Magento обрабатывает автоматическую сериализацию/нерешенство содержимого при загрузке данных из базы данных и перед сохранением объекта.
Это работает отлично, но когда я перечисляю на коллекцию этих объектов, содержимое поля не является автоматически. Я пытался с $collection->walk('afterLoad')
Но вскоре понял, что unserializeFields()
запускается в модели ресурса load()
, а не в afterLoad()
Как я впервые подумал. Какова лучшая практика в этом случае? Как мне автоматически не провести это поле. Я, конечно, могу перезагрузить объект в моей петле, делая что -то вроде $object = $object->load($object->getId())
, но мне было интересно, есть ли более разумный способ достичь этого.
Решение
Я, конечно, могу перезагрузить объект в моей петле, делая что -то вроде
$object = $object->load($object->getId())
Это нет Перезагрузка - это нагрузка. Анкет Элементы (модель экземпляров) в коллекциях не загружен. У них просто было применено ассоциативное множество данных о строках результатов. Это важная и немного запутанная разница между этими экземплярами модели, принадлежащими коллекции и данными, которые являются данными самозагрузки через модель их ресурсов.
В вашей коллекции _afterLoad()
, итерация над _items
а также unserialize()
соответствующее поле:
protected function _afterLoad()
{
parent::_afterLoad();
foreach ($this->getItems() as $item) {
$item->setData('field',unserialize($item->getData('field')));
$item->setDataChanges(false);
//The above sets items as not dirty.
//Value will be serialized on save via resource model.
}
return $this;
}
Другие советы
Чтобы сделать это для коллекций продуктов, я добавил слушателя событий catalog_product_collection_load_after
и итерация над всеми продуктами.
/**
* Apply backend manipulations of attributes to collection items.
* Listens to catalog_product_collection_load_after.
*
* @param Varien_Event_Observer $observer
* @return Mage_Catalog_Model_Observer
*/
public function loadCollectionAttributes(Varien_Event_Observer $observer)
{
$collection = $observer->getCollection();
/* @var $collection Mage_Catalog_Model_Resource_Product_Collection */
foreach ($collection as $product) {
/* @var $product Limora_Catalog_Model_Product */
foreach ($product->getAttributes() as $attribute) {
/* @var $attribute Mage_Eav_Model_Attribute */
$attribute->getBackend()->afterLoad($product);
}
}
}
Или проще, в вашей коллекции модели ресурсов:-
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection { protected function _afterLoad() { parent::_afterLoad(); foreach ($this->getItems() as $item) { $this->getResource()->unserializeFields($item); $item->setDataChanges(false); } return $this; } }