उत्पाद विशेषताओं में शामिल होने के लिए सबसे अच्छा अभ्यास


11

मेरे पास उत्पाद संदर्भ के साथ एक कस्टम टेबल है product_id। अब मैं अपने बैकएंड ग्रिड में उत्पाद जानकारी (sku, name) दिखाना चाहूंगा , लेकिन मैं अनिश्चित हूं कि ऐसा करने के लिए सबसे अच्छा अभ्यास क्या है?

मेरा सबसे अच्छा अनुमान SKUइस प्रकार है:

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

( मेरे ग्रिड ब्लॉक वर्ग में विधि से कोड _prepareCollection() )

लेकिन उत्पाद के नाम के बारे में क्या? इसे कैटलॉग_प्रोडक्ट_एंटिटी_वरच में पाया जा सकता है। मेरी समझ यह है कि आप इसे आसानी से प्राप्त कर सकते हैं यदि आपका स्वयं का संसाधन मॉडल और संग्रह आधारित है Mage_Eav_Model_Entity_Collection_Abstractक्योंकि तब आप इस तरह के तरीकों का उपयोग कर सकते हैं joinAttribute। लेकिन मेरा मॉडल एक साधारण तालिका पर आधारित है और इसका विस्तार किया गया है Mage_Core_Model_Resource_Db_Collection_Abstractऔर कोई joinAttributeविधि उपलब्ध नहीं है।

तो इस मामले में उत्पाद का नाम पाने का सबसे अच्छा तरीका क्या है?

आपके समय एवं मदद के लिए धन्यवाद :-)

अपडेट: अधिक सटीक होने के लिए, मैं अपने संसाधन मॉडल और संग्रह के बारे में बात कर रहा था। यह एक साधारण फ्लैट टेबल से मेल खाता है जैसे कुछ विशेषताओं के साथ

entity_id    product_id    created_at    user_id

मेरा इरादा बैकएंड में ग्रिड करना है जहां मैं कुछ आंकड़े दिखाता हूं:

ProductSku    Count(ProductSku)    MAX(created_at)

जहां तक ​​मुझे पता है, ऐसा करने के लिए सबसे अच्छा दृष्टिकोण ग्रिड ब्लॉक क्लास और जाने की विधि है _prepareCollection()

मेरा तरीका इस तरह दिखता है:

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

यह स्कु के लिए अच्छी तरह से काम करता है (जिसे मैं _prepareColums()विधि में product_sku के रूप में संदर्भित करता हूं । लेकिन joinनाम (और उदाहरण के लिए निर्माता) प्राप्त करने के लिए मुझे यहां क्या डालने की आवश्यकता है?

क्या मैं कुछ गलत कर रहा हूँ क्योंकि मैं उपयोग नहीं कर सकता हूँ joinLeft()?

जवाबों:


13

अपने संग्रह वर्ग में ( /Some/Module/Model/Mysql4 (or Resource)/YourModel/Collection.php) इस विधि को जोड़ें:

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

अपने ग्रिड ब्लॉक में इस फ़ंक्शन का उपयोग करें:

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

यह आशाजनक लग रहा है, लेकिन यह दुर्भाग्य से काम नहीं करता है। मेरे संग्रह का विस्तार हुआ Mage_Core_Model_Resource_Db_Collection_Abstractऔर मुझे एक त्रुटि मिली Call to undefined method Mycompany_Module_Model_Resource_Mymodel_Collection::joinLeft()। मुझे लगता है कि यह इसलिए है क्योंकि मैं एक ईएवी संसाधन मॉडल का उपयोग नहीं करता हूं?
सेलल्डवेलर


doh! मुझे अब बेवकूफ लग रहा है! ;-) और मुझे नहीं पता कि मैंने इसकी कोशिश क्यों की। आपका बहुत बहुत धन्यवाद!
सेलडवेलर

@Celldweller, आपको $this->_map['fields']['sku'] = 'sku'इस मामले में पूरी तरह से उपयोग या समान करने की आवश्यकता नहीं है । आपको इसकी आवश्यकता तभी है जब आपके पास कई समान फ़ील्ड नाम हों और विरोधों को रोकने के लिए अनुवाद करने की आवश्यकता हो। यह सिर्फ इस उपयोग के मामले के लिए ओवरहेड जोड़ रहा है। एक अलग उपयोग के मामले में, आप उपयोग कर सकते हैं $this->_map['fields']['my_sku'] = 'sku'तो आप और संग्रह के साथ उपयोग कर सकते हैं _prepareColumns: $this->addColumn('my_sku', array(…)), यह आप को छानने या छँटाई स्तंभों के लिए संघर्ष को रोकने के लिए मदद से आप एक क्षेत्र है, तो skuसंग्रह करने के लिए विभिन्न DB टेबल आम में इस्तेमाल किया
सिल्वेन Raye

बहुत बढ़िया जवाब! यह "आइटम के साथ एक ही आईडी पहले से मौजूद है" हालांकि मुद्दों को जन्म दे सकता है। एक साधारण $this->getSelect()->group('main_table.product_id');समस्या को हल करता है, लेकिन शायद कोड को अनुकूलित किया जा सकता है, ताकि पहली बार में डुप्लिकेट न बनाए जाएं?
साइमन

4

हाय Celldweller मुझे आशा है कि आप अच्छा कर रहे हैं :-)

हो सकता है कि आप वर्ग के बारे में अपने स्पष्टीकरण में गलत थे Mage_Core_Model_Resource_Db_Collection_Abstract, आप एक संसाधन संग्रह का विस्तार करते हैं न कि मॉडल का क्योंकि आप Magento संरचना का सम्मान करना चाहते हैं, तो आपको संग्रह वर्ग के साथ एक मॉडल का विस्तार नहीं करना चाहिए। क्या मैं सही हू?

मेरे सुधार के आधार पर, मुझे विभिन्न प्रकार के दृष्टिकोण मिलते हैं, जो इस बात पर निर्भर करता है कि आप उत्पाद का नाम विशेषता कितनी बार प्राप्त करना चाहते हैं। किसी भी मामले में, मुझे लगता है कि Magento फ्रेमवर्क के माध्यम से एक sql क्वेरी करना सबसे अच्छा तरीका और कुशल है। यह Mage::getModel('catalog/product')->load(1234)->getName()प्रत्येक भरी हुई वस्तु के लिए करने की तुलना में अधिक तेज़ है । तो वास्तव में यह आपके द्वारा उपयोग किए जाने वाले कोड के समान होगाsku

CODE नहीं परीक्षण किया गया

आप चाहते हैं कि जब भी कोई संग्रह लोड हो, तो वे जानकारी प्राप्त करें

आप _beforeLoadइस तरह के कोड में एक विधि में सेट अपने संग्रह वर्ग में हो सकता है :

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

आप ग्रिड के लिए केवल उन जानकारी चाहते हैं

अपने में _prepareCollection, आपको अपने संग्रह में एक विधि को उसी कोड के साथ जोड़ना होगा जैसा कि ऊपर किया गया था _beforeLoadतब आप इस विधि का उपयोग करके संग्रह तैयार कर सकते हैं। दोनों का उपयोग न करें, मेरा मतलब है कि एक ही कोड इन _beforeLoadऔर addProductNameविधियों का एक साथ उपयोग न करें , उनमें से केवल एक का उपयोग करें। यहाँ एक नमूना है:

अपने में grid.php:

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

अपने संग्रह में।

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

आपको दोबारा पढ़ने के लिए महान :-) बहुत बहुत धन्यवाद, लेकिन मैं joinLeft () विधि का उपयोग नहीं कर सकता। मुझे लगता है कि यह एक ईएवी संसाधन मॉडल-केवल विधि है? आप सही थे, मैं अपने शुरूआती प्रश्न में असमर्थ था। मैं इसे संपादित करूंगा :)
Celldweller

ओह और btw: बेशक मैं ऐसी स्थिति में एक उत्पाद-> लोड () नहीं करना चाहता। मुझे गोली मार दो अगर मैं कभी हिम्मत करता! ;-) मेरा लक्ष्य ग्रिड में छँटाई और छानने में सक्षम होने के लिए एक संग्रह में यह सब करना है। अधिक जानकारी के लिए मेरी प्रारंभिक पोस्ट में अद्यतन देखें।
सेलडवेलर

इसलिए joinLeft को ज्वाइन करें लेकिन आपने पहले ही दूसरे उत्तर को स्वीकार कर लिया है, हालांकि मैंने सही उत्तर दिया है और उत्तर देने वाला पहला है :-(
सिल्वेन रे

हाँ आप सही है। मैं बहुत खुश था कि यह आखिरकार काम कर गया, कि मैंने इसके बारे में सोचा नहीं था। मैं आप दोनों की बहुत शुक्रगुजार हूं। आशा है आप मुझे क्षमा कर सकते हैं! मुझ पर आपकी एक बीयर उधार है।
सेलेडवेलर

अहा कोई चिंता नहीं। हम आपसे बर्लिन में मिलते हैं :-)
सिल्वेन रेये

4

मुझे लगभग एक ही समस्या थी, लेकिन मैं एक टिप्पणी नहीं जोड़ सकता, क्योंकि मेरे पास 50 प्रतिष्ठा नहीं है। मैंने यह जानने में बहुत समय बिताया कि क्या गलत है (मैंने सिल्वेन रे का कोड इस्तेमाल किया)। किसी कारण से मेरा उत्पाद संग्रह फ़िल्टर किया गया। तो मुझे एक कारण मिला।

यदि आप कुछ आयात उपकरण (मैगमी, आदि) का उपयोग कर रहे हैं, तो वे अक्सर एक बार में खाली विशेषता नहीं बनाते हैं। इसलिए उन ->where("product_attribute.attribute_id = ?", $productName->getId())उत्पादों का उपयोग करना जिनके पास यह विशेषता नहीं है, चयन से गायब हो जाएंगे।

सही तरह से उपयोग कर रहा 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());

आशा है कि यह किसी की मदद करता है।


-2

उत्पाद ग्रिड पर कस्टम विशेषता प्रदर्शित करें।

कृपया अपने एक्सटेंशन में इस ब्लॉक Mage_Adminhtml_Block_Catalog_Product_Grid को ओवरराइट करें और अपने एक्सटेंशन की ब्लॉक फ़ाइल में _prepareCollection और _prepareColumns को कॉपी करें।

इस ग्रिड से पहले उत्पाद ग्रिड Mage_Adminhtml_Block_Catalog_Patalog_Grid के ग्रिड में _prepareCollection फ़ंक्शन का चयन करने के लिए नीचे कोड जोड़ें-> setCollection ($ संग्रह) लाइन।

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

और फिर ग्रिड के _prepareColumns फ़ंक्शन में कॉलम के लिए नीचे कोड।

$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,

            ));
        }

कोर फ़ाइलें बदलें कोई अच्छा अभ्यास नहीं है। उसी के लिएnew SomeModel()
sv3n

हमें कोर फाइल में बदलाव नहीं करना है। हम अपनी कार्यक्षमता को पूरा करने के लिए उस ब्लॉक (Mage_Adminhtml_Block_Catalog_Patalog_Grid) को ओवरराइट कर सकते हैं
5
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.