Domanda

Ho un modello personalizzato e modello di risorse. Voglio caricare una singola istanza del modello utilizzando più di 1 campo.

Il modello ha i seguenti campi:

id
tag_name
custom_name
group_name

voglio caricare questo modello basato su su tag_name, custom_name e nome_gruppo invece di id.

Attualmente sto usando una collezione e addFilter per ogni campo. Questo funziona, ma mi chiedevo se v'è una strategia standard per questo tipo di cose in Magento?

Modifica

core Magento non sembra collezioni di utilizzo di questo scenario, ma invece utilizza le query SQL dirette nei modelli di risorse.

Un esempio di questo è:

loadByAccountAndDate() in Mage_Paypal_Model_Resource_Report_Settlement

C'è una ragione per questo, quando le collezioni sembrano essere un modo più conciso, in termini di quantità di codice da scrivere

Lo so appena non per questo sceglie di Magento da fare in questo modo

È stato utile?

Soluzione

Credo che questo sia un approccio buono. Forse è necessario creare un wrapper nella classe del modello in modo da evitare di scrivere la stessa cosa più e più volte.
Qualcosa di simile:

public function loadByMultiple($tag, $customName, $group){
    $collection = $this->getCollection()
            ->addFieldToFilter('tag_name', $tag)
            ->addFieldToFilter('custom_name', $customName)
            ->addFieldToFilter('group_name', $group);
    return $collection->getFirstItem();
}

E si può caricare l'elemento come questo in qualsiasi altro posto:

$model = Mage::getModel('model/class_here')->loadByMultiple($tag, $customName, $group);
if ($model->getId()){
   //the instance exists
}
else{
    //not found
}

Altri suggerimenti

Modulo / Modello / SomeModel.php

public function loadByAttributes($attributes)
{
    $this->setData($this->getResource()->loadByAttributes($attributes));
    return $this;
}

Modulo / Modello / Resource / SomeModel.php:

public function loadByAttributes($attributes)
    {
        $adapter = $this->_getReadAdapter();
        $where   = array();
        foreach ($attributes as $attributeCode=> $value) {
            $where[] = sprintf('%s=:%s', $attributeCode, $attributeCode);
        }
        $select = $adapter->select()
            ->from($this->getMainTable())
            ->where(implode(' AND ', $where));

        $binds = $attributes;

        return $adapter->fetchRow($select, $binds);
    }

E infine si può caricare il modello seguente:

$attributes = array('tag_name'=> 'any', 'custome_name'=> 'some','group_name'=>'some');
$model      = Mage::getModel('module/somemodel')->loadByAttributes($attributes);

Aggiornamento

Tra l'altro è possibile utilizzare questo metodo (loadByAttributes) facilmente piuttosto che la raccolta ed è più comprensibile. Magento invia anche alcuni eventi mentre raccolta caricamento o entità ed estensione terzi possono aggiornare raccolta o entità dall'osservatore. Se si carica l'entità tramite risorse (data in esempio di mio e tuo) nessun caso / osservatori fuoco e si può ottenere entità "pulito" più veloce, piuttosto che di raccolta. Inoltre Magento non utilizza collezione memorizzata nella cache in questo modo, lo carica direttamente dalla tabella db.
forse questo è motivo di utilizzare questo metodo con moduli di base Magento.

Si sta facendo bene con addFilter. In Magento è possibile caricare da qualsiasi attributo ma non più attributi in una sola volta. Con l'aggiunta di filtri a raggiungere lo stesso effetto senza spese extra.

In primo luogo - la vostra strategia per filtrare una collezione è corretta. Perché collezioni in Magento pigro carico si ha la possibilità di creare i metodi nel modello di risorse per più strettamente definire i requisiti del vostro carico personalizzato.

Senza alcuno del vostro codice per esempio, si consideri il seguente pseudo-metodo nel modello di risorse:

<?php


class Marty_Wallace_Model_Resource_Method extends Mage_Core_Model_Resource_Db_Abstract{

    protected function _construct()
    {
        $this->_init('yourmodel/table', 'entity_id');
    }

    public function loadByCriteria(array $filter)
    {

        //$filter should be array('columnname'=>'value','columname'=>'value')

        $collection = Mage::getModel('yourmodel/class')->getCollection();

        foreach($filter as $column=>$value){
            $collection->addFieldToFilter($column,$value);
        }

        return $collection;

    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a magento.stackexchange
scroll top