Frage

In meinem Ressourcenmodell habe ich ein Feld als serialisierbar definiert (siehe Eigenschaft $_serializableFields in Mage_Core_Model_Resource_Db_Abstract): Magento verarbeitet automatisch Serialisierung/Weiterlinge des Inhalts beim Laden von Daten aus der Datenbank und vor dem Speichern des Objekts.

Dies funktioniert perfekt, aber wenn ich eine Sammlung dieser Objekte iteriere, werden der Feldinhalt nicht automatisch unverzweigt. Ich habe es versucht mit $collection->walk('afterLoad') Aber das merkte das bald unserializeFields() wird im Ressourcenmodell ausgelöst load(), und nicht in afterLoad() Wie ich zum ersten Mal gedacht habe. Was ist in diesem Fall die beste Praxis? Wie bekomme ich dieses Feld automatisch unverzweigt? Ich kann das Objekt natürlich in meiner Schleife neu laden und so etwas tun wie $object = $object->load($object->getId()), aber ich habe mich gefragt, ob es eine intelligentere Möglichkeit gibt, dies zu erreichen.

War es hilfreich?

Lösung

Ich kann das Objekt natürlich in meiner Schleife neu laden und so etwas tun wie $object = $object->load($object->getId())

Das ist nicht eine Reload - dies ist eine Last. Elemente (Modellinstanzen) in Sammlungen sind nicht geladen. Sie hatten lediglich eine assoziative Reihe von Ergebnisdaten, die auf sie angewendet wurden. Es ist ein wichtiger und leicht verwirrender Unterschied zwischen diesen Modellinstanzen in Sammlungen und denen, die über ihr Ressourcenmodell selbst geladen werden.

In der Ihrer Sammlung _afterLoad(), über die _items und unserialize() das entsprechende Feld:

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

Andere Tipps

Um dies für Produktsammlungen zu tun, habe ich einen Event -Hörer hinzugefügt catalog_product_collection_load_after und um alle Produkte zu iterieren.

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

Oder einfacher in Ihrer Ressourcenmodellsammlung:-

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;
   }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top