Вопрос

В моей модели ресурса я определил поле как сериализуемое (см. Свойство $_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;
   }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top