Magento - özel (eav olmayan) model, birden fazla alana göre yükleme


15

Özel bir modelim ve kaynak modelim var. Birden fazla alan kullanarak modelin tek bir örneğini yüklemek istiyorum.

Model aşağıdaki alanlara sahiptir:

id
tag_name
custom_name
group_name

Bu modeli id ​​yerine tag_name, custom_name ve group_name tabanlı yüklemek istiyorum.

Şu anda her alan için bir koleksiyon ve addFilter kullanıyorum. Bu çalışıyor, ama Magento bu tür bir şey için standart bir strateji olup olmadığını merak ettim?

DÜZENLE

Çekirdek macgento bu senaryo için koleksiyonları kullanmak gibi görünmüyor, bunun yerine kaynak modellerinde doğrudan sql sorguları kullanıyor.

bunun bir örneği:

loadByAccountAndDate() içinde Mage_Paypal_Model_Resource_Report_Settlement

Koleksiyonların yazılacak kod miktarı açısından daha özlü bir şekilde göründüğü bir sebep var mı?

Magento'nun neden bu şekilde yapmayı seçtiğini bilmiyorum

Yanıtlar:


22

Bence bu iyi bir yaklaşım. Belki aynı şeyi tekrar tekrar yazmaktan kaçınmak için model sınıfında bir sarıcı oluşturmanız gerekir.
Gibi bir şey:

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

Ve başka herhangi bir yere böyle bir şey yükleyebilirsiniz:

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

Sorularımı koleksiyonları kullanma konusundaki endişelerimle güncelledim
Marty Wallace

Eğer koleksiyonları gerçekten mantığınızdan çıkarmak istiyorsanız, @mageUz'un cevabında ne yazdığını kontrol edin. Test etmedim, ama iyi bir fikir gibi dikişler. Not: Koleksiyonları kullanırken hala herhangi bir sorun görmüyorum.
Marius

Onları hariç tutmak istemem, ama magento en iyi uygulamaları kullanmak istiyorum. Çekirdek kod belirli bir şekilde bir şey yapıyorsa, bu genellikle takip edilecek bir şeyin işareti olmalıdır. Ama bu durumda gerçekten en iyi yolu bilmiyorum gibi bu forumda rehberlik istiyorum
Marty Wallace

1
Bu durumda koleksiyonları kullanma konusunda da endişelerim var. Muhtemelen söz konusu koleksiyonun _itemObjectClassaslında çağıran modelle aynı olan bir koleksiyonu vardır loadByMultiple. Sonuç olarak, $x = Mage::getModel('some/model')bir modelin bir örneği olmaz ve $x->loadByMultiple($tag, $customName, $group)aslında farklı / yeni bir örnek olmaz mı?
kojiro

@kojiro. Evet, farklı bir örnek olacak ama öyle olacak loadByAttribute. Referans için bu soruya bakın: magento.stackexchange.com/q/5926/146
Marius

7

Modül / Model / SomeModel.php

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

Modül / Model / Kaynak / 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);
    }

Ve son olarak aşağıdaki modeli yükleyebilirsiniz:

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

Güncellenmiş

Bu arada, bu (loadByAttributes) yöntemini toplama yerine kolayca kullanabilirsiniz ve daha anlaşılır. Magento ayrıca koleksiyon veya varlık yüklerken bazı olaylar gönderir ve üçüncü taraf uzantı koleksiyon veya varlığı gözlemci tarafından güncelleyebilir. Varlığı kaynak (benimki ve sizinki olarak verilir) aracılığıyla yüklerseniz hiçbir olay / gözlemci tetiklenmez ve toplama yerine "temiz" varlığı daha hızlı alabilirsiniz. Ayrıca Magento önbelleğe alınmış koleksiyonu bu şekilde kullanmaz, doğrudan db tablosundan yükler.
Belki de bu yöntemi Magento çekirdek modülleri tarafından kullanmanın nedeni budur.


Bence bu satırda bir getData () eksik:, $this->setData($this->getResource()->loadByAttributes($attributes));olması gereken: değil $this->setData($this->getResource()->loadByAttributes($attributes)->getData()); mi?
Mihai MATEI

2

İle doğru yapıyorsun addFilter. Magento'da aynı anda birden çok özelliğe değil, herhangi bir özelliğe göre yükleme yapabilirsiniz. Filtreler ekleyerek ek bir ek yük olmadan aynı etkiyi elde edersiniz.


Bir db select kullanmak bir koleksiyon kullanmaktan daha iyi olmaz mıydı?
Marty Wallace

Sizce ne addFilteryapıyor? :-)
user487772

Mage_Paypal_Model_Resource_Report_Settlement içindeki loadByAccountAndDate () öğesine bakabilir, çünkü bu koleksiyon yerine bir seçim kullanıyor
Marty Wallace

Ve aslında çekirdek koddaki bu durum neredeyse sadece böyle ve koleksiyonları kullanarak herhangi bir şey göremiyorum
Marty Wallace

1
Sorularımı koleksiyonları kullanma konusundaki endişelerimle güncelledim
Marty Wallace

1

İlk olarak - bir koleksiyonu filtreleme stratejiniz doğrudur. Magento tembel yüklemedeki koleksiyonlar, özel yükünüzün gereksinimlerini daha sıkı tanımlamak için kaynak modelinizde yöntemler oluşturma yeteneğine sahip olursunuz.

Örnekleme kodunuzdan bazıları olmadan, Kaynak Modelinizde aşağıdaki sözde yöntemi göz önünde bulundurun:

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

    }
}

Bu özel kullanım durumu için koleksiyonları kullanma konusundaki endişelerimle sorumu güncelledim, ancak magento'nun neden bu şekilde yapıldığını bilmek için yeterli bilgiye sahip değilim
Marty Wallace
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.