Ürün özelliklerine katılmak için en iyi uygulama


11

Ürün referanslı özel bir tablo var product_id. Şimdi arka uç ızgaramda ürün bilgilerini (sku, isim) göstermek istiyorum , ancak bunu yapmak için en iyi uygulamanın ne olduğundan emin değilim?

Benim en iyi tahminim SKUşöyledir:

$collection->join(
    'catalog/product',
    'product_id=`catalog/product`.entity_id',
    array('product_sku' => 'sku')
)

( ızgara bloğu sınıfımdaki yöntemden kod _prepareCollection() )

Peki ürün adı ne olacak? Bu, catalog_product_entity_varchar içinde bulunabilir. Anladığım kadarıyla, kendi kaynak modeliniz ve koleksiyonunuz temel alındığında bunu kolayca elde edebilirsiniz, Mage_Eav_Model_Entity_Collection_Abstractçünkü o zaman gibi yöntemleri kullanabilirsiniz joinAttribute. Ancak modelim basit bir tabloya dayanıyor ve genişliyor Mage_Core_Model_Resource_Db_Collection_Abstractve joinAttributekullanılabilir bir yöntem yok .

Peki bu durumda ürün adını almanın en iyi yolu nedir?

Zaman ayırdığınız ve yardım ettiğiniz için teşekkürler :-)

Güncelleme: Daha kesin olmak gerekirse, kaynak modelim ve koleksiyonum hakkında konuşuyordum. Basit bir düz tabloyu, yalnızca birkaç özellikle eşleştirir.

entity_id    product_id    created_at    user_id

Amacım bazı istatistikleri gösterdiğim arka uçta ızgara yapmaktır:

ProductSku    Count(ProductSku)    MAX(created_at)

Bildiğim kadarıyla, bunu yapmak için en iyi yaklaşım ızgara blok sınıfı üzerinden ve gitmek için yöntemdir _prepareCollection().

Benim yöntem şöyle görünür:

protected function _prepareCollection()
{
    // Get and set our collection for the grid
    $collection = Mage::getResourceModel($this->_getCollectionClass());
    $collection
        ->join(
            'catalog/product',
            'product_id=`catalog/product`.entity_id',
            array('product_sku' => 'sku')
            )
        ->addExpressionFieldToSelect('product_count', 'COUNT({{product_id}})', 'product_id')
        ->addExpressionFieldToSelect('newest', 'MAX({{created_at}})', array('created_at'=>'main_table.created_at'))
        ->getSelect()->group('product_id');
    $this->setCollection($collection);

    return parent::_prepareCollection();
}

Bu sku ( _prepareColums()yöntemde product_sku olarak adlandırdığım . join)

Kullanamadığım için yanlış bir şey mi yapıyorum joinLeft()?

Yanıtlar:


13

Koleksiyon sınıfınıza ( /Some/Module/Model/Mysql4 (or Resource)/YourModel/Collection.php) şu yöntemi ekleyin:

public function addProductData()
    {
        /** add particular attribute code to this array */
        $productAttributes = array('name', 'price', 'url_key');
        foreach ($productAttributes as $attributeCode) {
            $alias     = $attributeCode . '_table';
            $attribute = Mage::getSingleton('eav/config')
                ->getAttribute(Mage_Catalog_Model_Product::ENTITY, $attributeCode);

            /** Adding eav attribute value */
            $this->getSelect()->join(
                array($alias => $attribute->getBackendTable()),
                "main_table.product_id = $alias.entity_id AND $alias.attribute_id={$attribute->getId()}",
                array($attributeCode => 'value')
            );
            $this->_map['fields'][$attributeCode] = 'value';
        }
        /** adding catalog_product_entity table fields */
        $this->join(
            'catalog/product',
            'product_id=`catalog/product`.entity_id',
            array('sku' => 'sku', 'type_id' => 'type_id')
        );
        $this->_map['fields']['sku']     = 'sku';
        $this->_map['fields']['type_id'] = 'type_id';
        return $this;
    }

Izgara bloğunuzda bu işlevi kullanın:

 protected function _prepareCollection()
    {
        $collection = Mage::getModel('some/yourmodel')
            ->getCollection()->addProductData();
        $this->setCollection($collection);
        return parent::_prepareCollection();
    }

Bu umut verici görünüyor, ancak maalesef çalışmıyor. Koleksiyonum uzuyor Mage_Core_Model_Resource_Db_Collection_Abstractve bir hata alıyorum Call to undefined method Mycompany_Module_Model_Resource_Mymodel_Collection::joinLeft(). Sanırım bunun nedeni bir EAV Kaynak Modeli kullanmıyorum.
Celldweller

JoinLeft yerine join kullan, cevabı düzenledim
mageUz

doh! Şimdi kendimi aptal hissediyorum! ;-) Ve neden denediğimi bilmiyorum. Çok teşekkür ederim!
Celldweller

@Celldweller, $this->_map['fields']['sku'] = 'sku'bu durumda kesinlikle kullanmanıza veya benzeri bir şeye ihtiyacınız yoktur . Buna yalnızca birkaç aynı alan adınız varsa ve çakışmaları önlemek için çeviri yapmanız gerekiyorsa ihtiyacınız vardır. Sadece bu kullanım durumu için ek yük ekler. Farklı bir kullanım durumunda, $this->_map['fields']['my_sku'] = 'sku'koleksiyonla birlikte kullanabilirsiniz ve _prepareColumns:, koleksiyonla ortak farklı DB tablolarında kullanılan $this->addColumn('my_sku', array(…))bir alanınız varsa, filtreleme veya sütun sıralama için çakışmayı önlemenize yardımcı olacaktırsku
Sylvain Rayé

Mükemmel cevap! Yine de "aynı kimliğe sahip öğe zaten var" sorunlarına yol açabilir. Basit bir $this->getSelect()->group('main_table.product_id');sorunu çözer, ancak belki kod optimize edilebilir, böylece kopyalar ilk etapta yaratılmaz?
Simon

4

Merhaba Celldweller Umarım iyi gidiyorsun :-)

Belki de sınıfla ilgili açıklamalarınızda yanılıyorsunuz Mage_Core_Model_Resource_Db_Collection_Abstract, Magento yapısına saygı göstermek istiyorsanız koleksiyon sınıfına sahip bir modeli genişletmemeniz gerektiğinden, modeli değil bir kaynak koleksiyonunu genişletiyorsunuzdur. Haklı mıyım?

Düzeltmeme dayanarak, ürün adı özelliğini ne sıklıkta almak istediğinize bağlı olarak farklı tür yaklaşımlar görüyorum. Her durumda, Magento Framework üzerinden bir sql sorgusu yapmanın en iyi yol ve verimli olduğunu düşünüyorum. Mage::getModel('catalog/product')->load(1234)->getName()Yüklenen her öğe için a yapmaktan daha hızlıdır . Yani aslında bu kod için kullandığınız koda çok benzersku

KOD TEST EDİLMEDİ

Her koleksiyon yüklendiğinde bu bilgileri istiyorsunuz

Koleksiyon sınıfınızda _beforeLoadböyle bir kod oluşturabilirsiniz:

protected function _beforeLoad()
{
    $productName = Mage::getSingleton('eav/config')->getAttribute('catalog_product','name');

    $this->getSelect()
        ->join( array('product_attribute' => $productName->getBackendTable()),
            'main_table.product_id = product_attribute.entity_id',
            array())
        ->where("product_attribute.attribute_id = ?", $productName->getId());
    }

    return parent::_beforeLoad();
}

Bu bilgileri SADECE ızgara için istiyorsunuz

İçinde, _prepareCollectionkoleksiyonunuza yukarıdaki ile aynı kodla bir yöntem eklemek zorunda kalacaksınız, _beforeLoaddaha sonra bu yöntemi kullanarak koleksiyonu hazırlayabilirsiniz. Her ikisini de kullanmayın, yani aynı kodu _beforeLoadve addProductNameyöntemleri birlikte kullanmayın, bunlardan sadece birini kullanın. İşte bir örnek:

Içine grid.php:

protected function _prepareCollection()
{
    ...
    $collection->addProductName();
    $this->setCollection($collection);
    return parent::_prepareCollection();
}

Collection.php'nize:

public function addProductName()
{
    $productName = Mage::getSingleton('eav/config')->getAttribute('catalog_product','name');

    $this->getSelect()
        -> join( array('product_attribute' => $productName->getBackendTable()),
            'main_table.product_id = product_attribute.entity_id',
            array())
        ->where("product_attribute.attribute_id = ?", $productName->getId());

    return $this;
}

Seni tekrar okumak harika :-) Çok teşekkür ederim ama joinLeft () yöntemini kullanamıyorum. Sanırım bu sadece bir EAV kaynak modeli yöntemidir? Haklıydın, ilk sorumda kesin değildim. Düzenleyeceğim :)
Celldweller

Oh ve btw: Elbette böyle bir durumda bir ürün-> load () yapmak istemiyorum. Cesaret edersem beni vur! ;-) Amacım ızgara içinde sıralama ve filtreleme yapabilmek için hepsini tek bir koleksiyona sahip olmaktır. Daha fazla bilgi için ilk yazımdaki güncellemeye bakın.
Celldweller

Bu yüzden joinLeft'i birleştirme ile değiştirin, ancak doğru yanıtı verdim ve ilk cevaplayana rağmen diğer cevabı zaten kabul
ettiniz

Evet haklısın. O kadar mutluydum ki sonunda işe yaradı, düşünmedim. İkinize de çok müteşekkirim. Umarım beni affedebilirsin! Sana bir bira borçluyum.
Celldweller

ahah endişelenme. Berlin'de sizleri memnuniyetle karşılıyoruz :-)
Sylvain Rayé

4

Neredeyse aynı sorunum vardı, ama yorum ekleyemiyorum, çünkü 50 itibarım yok. Neyin yanlış olduğunu anlamaya çalışmak için çok zaman harcadım (Sylvain Rayé'nin kodunu kullandım). Ürün koleksiyonum bir nedenle filtrelendi. Bir sebep buldum.

Bazı içe aktarma araçlarını (magmi vb.) Kullanıyorsanız, bunlar genellikle aynı anda boş özellikler oluşturmaz. Bu nedenle ->where("product_attribute.attribute_id = ?", $productName->getId()), bu özelliğe sahip olmayan ürünleri kullanmak seçimden kaybolacaktır.

Doğru yol şu şekildedir joinLeft:

$productName = Mage::getSingleton('eav/config')->getAttribute('catalog_product','name');

$this->getSelect()
     ->joinLeft(array('product_attribute' => $productName->getBackendTable()),
        "main_table.product_id = product_attribute.entity_id AND
         product_attribute.attribute_id = {$productName->getId()}",
        array());

Umarım bu birine yardımcı olur.


-2

Ürün ızgarasında özel özellik görüntüleme.

Lütfen uzantınızdaki Mage_Adminhtml_Block_Catalog_Product_Grid bloğunun üzerine yazın ve _prepareCollection ve _prepareColumns işlevlerini uzantınızın blok dosyasına kopyalayın.

$ This-> setCollection ($ collection) satırından önce Mage_Adminhtml_Block_Catalog_Product_Grid ürün ızgarasının _prepareCollection işlevinde attribuet seçmek için aşağıdaki kodu ekleyin.

$attributeCode = 'qc_status';//here your attribute code
        $collection->joinAttribute($attributeCode, 'catalog_product/'.$attributeCode, 'entity_id', null, 'left');
        $collection->addAttributeToSelect($attributeCode);

Ve sonra kılavuzun _prepareColumns işlevinde sütun için kodun altında.

$attributeCodeConfig ='qc_status';//Your attribute code...

        $attributeId = Mage::getResourceModel('eav/entity_attribute')->getIdByCode('catalog_product', $attributeCodeConfig);

        $attribute = Mage::getModel('catalog/resource_eav_attribute')->load($attributeId);
        $attributeData = $attribute->getData();
        $frontEndLabel = $attributeData['frontend_label'];

        $attributeOptions = $attribute->getSource()->getAllOptions();
        $b = new Mage_Catalog_Model_Resource_Eav_Attribute();
        $attributeOptions2 = array();
        foreach ($attributeOptions as $value) {
            if(!empty($value['value'])) {
                $attributeOptions2[$value['value']] = $value['label'];
            }

        }


        if(count($attributeOptions2) > 0) {
            $this->addColumn($attributeCodeConfig,
                array(
                    'header'=> Mage::helper('catalog')->__($frontEndLabel),
                    'width' => '80px',
                    'index' => $attributeCodeConfig,
                    'type'  => 'options',
                    'options' => $attributeOptions2,

            ));
        } else {
            $this->addColumn($attributeCodeConfig,
                array(
                    'header'=> Mage::helper('catalog')->__($frontEndLabel),
                    'width' => '80px',
                    'index' => $attributeCodeConfig,

            ));
        }

Çekirdek dosyaları değiştirmek iyi bir uygulama değildir. Aynı içinnew SomeModel()
sv3n

çekirdek dosyada değişiklik yapmak zorunda değiliz. işlevselliğimizi gerçekleştirmek için bu bloğun (Mage_Adminhtml_Block_Catalog_Product_Grid) üzerine yazabiliriz
Savoo
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.