Pregunta

En mi modelo de recurso que he definido un campo como serializable (ver $_serializableFields propiedad en Mage_Core_Model_Resource_Db_Abstract): mangos. Magento automáticamente la serialización / unserialization de los contenidos cuando la carga de datos de la base de datos y antes de guardar el objeto

Esto funciona perfectamente, pero cuando iterar sobre una colección de esos objetos, el contenido del campo no están decodificados de vuelta automáticamente. Probé con $collection->walk('afterLoad') pero pronto se dio cuenta de que unserializeFields() se activa en el modelo de recursos load(), y no en afterLoad() como yo pensaba. ¿Cuál es la mejor práctica en este caso? ¿Cómo consigo este campo decodificado de forma automática? Por supuesto que puedo recargar el objeto en mi lazo, haciendo algo como $object = $object->load($object->getId()), pero me preguntaba si hay una manera más inteligente para lograrlo.

¿Fue útil?

Solución

Me puede volver a cargar, por supuesto, el objeto en mi lazo, haciendo algo como $object = $object->load($object->getId())

Este es no una recarga - se trata de una carga . Artículos (instancias de modelo) en colecciones son no cargado. Simplemente han tenido una matriz asociativa de datos de fila de resultado que se les aplica. Es un importante y poco confuso diferencia entre estas instancias de modelo de propiedad de cobro y los que son datos de auto-carga a través de su modelo de recursos.

En _afterLoad() de su colección, iterar sobre la _items y unserialize() el campo apropiado:

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;
}

Otros consejos

Para hacer esto para colecciones de productos que añade un detector de eventos para catalog_product_collection_load_after y para iterar sobre todos los productos.

/**
 * 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);
        }
    }
}

o, más sencillamente, en su colección modelo de recursos: -

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;
   }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top