संग्रह में समूह खंड का उपयोग करते समय ग्रिड पेजेशन काम नहीं कर रहा है


9

मैं उत्पाद ग्रिड पर काम कर रहा हूं, लेकिन इसका पृष्ठांकन या उत्पाद गणना काम नहीं कर रही है (क्योंकि यह गलत गणना प्रदर्शित करता है)। मेरे ब्लॉक _preparecollection फ़ंक्शन के रूप में नीचे है। मैंने संग्रह में श्रेणी फ़िल्टर कोड जोड़ा है इसलिए मुझे पहले से मौजूद आईडी के लिए त्रुटि को रोकने के लिए समूह खंड का उपयोग करना होगा।

    protected function _prepareCollection()
    {
        $store = $this->_getStore();
        $collection = Mage::getModel('catalog/product')->getCollection()
            ->addAttributeToSelect('sku')
            ->addAttributeToSelect('name')
            ->addAttributeToSelect('attribute_set_id')
            ->addAttributeToSelect('type_id')
            ->joinField('category_id',
                'catalog/category_product',
                'category_id',
                'product_id=entity_id',
                null,
                'left');
$collection->addAttributeToFilter('category_id', array('in' => array(4,10)))
            ->distinct(true);
            $collection->getSelect()->group('e.entity_id');


        if (Mage::helper('catalog')->isModuleEnabled('Mage_CatalogInventory')) {
            $collection->joinField('qty',
                'cataloginventory/stock_item',
                'qty',
                'product_id=entity_id',
                '{{table}}.stock_id=1',
                'left');
        }
        $collection->joinField('position',
                'catalog/category_product',
                'position',
                'product_id=entity_id',
                null,
                'left');
        $collection->joinField('websites',
            'catalog/product_website',
            'website_id',
            'product_id=entity_id',
            null,
            'left');
        if ($store->getId()) {
            //$collection->setStoreId($store->getId());
            $adminStore = Mage_Core_Model_App::ADMIN_STORE_ID;
            $collection->addStoreFilter($store);
            $collection->joinAttribute(
                'name',
                'catalog_product/name',
                'entity_id',
                null,
                'inner',
                $adminStore
            );

            $collection->joinAttribute(
                'custom_name',
                'catalog_product/name',
                'entity_id',
                null,
                'inner',
                $store->getId()
            );
            $collection->joinAttribute(
                'status',
                'catalog_product/status',
                'entity_id',
                null,
                'inner',
                $store->getId()
            );
            $collection->joinAttribute(
                'visibility',
                'catalog_product/visibility',
                'entity_id',
                null,
                'inner',
                $store->getId()
            );
            $collection->joinAttribute(
                'price',
                'catalog_product/price',
                'entity_id',
                null,
                'left',
                $store->getId()
            );
        }
        else {
            $collection->addAttributeToSelect('price');
            $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
            $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
        }

        $this->setCollection($collection);

        parent::_prepareCollection();
        $this->getCollection()->addWebsiteNamesToResult();
        return $this;
    }

मेरे पास Google था और मुझे इसका उत्तर मिला और इसमें जोड़ा गया lib/varian/data/collection/db.php

    public function getSelectCountSql()
{
     $this->_renderFilters();

        $countSelect = clone $this->getSelect();
        $countSelect->reset(Zend_Db_Select::ORDER);
        $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
        $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
        $countSelect->reset(Zend_Db_Select::COLUMNS);

        if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0) {
            $countSelect->reset(Zend_Db_Select::GROUP);
            $countSelect->distinct(true);
            $group = $this->getSelect()->getPart(Zend_Db_Select::GROUP);
            $countSelect->columns("COUNT(DISTINCT ".implode(", ", $group).")");
        } else {
            $countSelect->columns('COUNT(*)');
        }
        return $countSelect;
}

यहां छवि विवरण दर्ज करें लेकिन कोई भी भाग्य कृपया इसे हल करने में मदद नहीं करता है


आप किस वर्ग का विस्तार कर रहे हैं? Mage_Adminhtml_Block_Widget_Grid?
B00MER

हाँ, मैं विस्तार कर रहा हूँMage_Adminhtml_Block_Widget_Grid
ज़हीरबास

GetSelectCountSql पर कौन-सी क्वेरी लौटाती है?
राजवंश

जवाबों:


17

Magento में संग्रह और आलसी लोड हो रहा है

कारण यह नहीं है कि संग्रह कैसे काम करते हैं और संग्रह के साथ आलसी लोडिंग कैसे काम करता है, इसका कारण है।

Magento में संग्रह कक्षा को लागू करता है Countable। मैगेंटो में संग्रह के आलसी लोडिंग के कारण, जब भी विधि count()को कॉल किया जाता है, तो डेटा लोड करना पड़ता है। इसके एक समाधान के रूप में, संग्रह नामक एक विधि को लागू करता है getSize()। यह आपके एसक्यूएल स्टेटमेंट को क्लोन करेगा, इसे एक में लपेटेगा COUNT()और परिणाम लौटाएगा। इसने एक संग्रह को सभी डेटा लोड किए बिना कुल गणना प्राप्त करने की अनुमति दी। यह अंतिम मिनट में फिल्टर जैसी चीजों को जोड़ने की अनुमति देता है।

यह क्या है Varien_Data_Collection_Db::getSize()और यह getSelectCountSql()कैसा दिखता है:

/**
     * Get collection size
     *
     * @return int
     */
    public function getSize()
    {
        if (is_null($this->_totalRecords)) {
            $sql = $this->getSelectCountSql();
            $this->_totalRecords = $this->getConnection()->fetchOne($sql, $this->_bindParams);
        }
        return intval($this->_totalRecords);
    }

    /**
     * Get SQL for get record count
     *
     * @return Varien_Db_Select
     */
    public function getSelectCountSql()
    {
        $this->_renderFilters();

        $countSelect = clone $this->getSelect();
        $countSelect->reset(Zend_Db_Select::ORDER);
        $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
        $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
        $countSelect->reset(Zend_Db_Select::COLUMNS);

        $countSelect->columns('COUNT(*)');

        return $countSelect;
    }

असल में, यह सीमाएं, कॉलम, ऑर्डरिंग आदि को छोड़ देता है और फिल्टर को पीछे छोड़ देता है। फिर यह COUNT()कॉलम में MySQL जोड़ता है ।

समस्या

आम तौर पर, एक मेज पर, यह कुल संख्या के साथ एक पंक्ति लौटाएगा। यही कारण है कि है getSize()एक करता है fetchOne()क्वेरी के खिलाफ। हालाँकि, जब टेबल टेबल, ग्रुप बाय, और लाइक जैसी चीजें करते हैं, तो आप एक पंक्ति में नहीं लौटेंगे, आप एक से अधिक होंगे। यह इस वजह से है कि आपको getSize()अपने संग्रह में विधि को बदलने की आवश्यकता है ।

समाधान

यह वही है जो आपकी विधि को अभी देखना चाहिए:

public function getSize() {

        if ( is_null( $this->_totalRecords ) ) {
            $sql = $this->getSelectCountSql();
            // fetch all rows since it's a joined table and run a count against it.
            $this->_totalRecords = count( $this->getConnection()->fetchall( $sql, $this->_bindParams ) );
        }

        return intval( $this->_totalRecords );
    }

इसके बजाय fetchOne(), हम fetchAll()एक count()PHP समारोह में लिपटे भाग गया । अब आपके योग उचित रूप से वापस आ जाएंगे।


2
यह है कि मैं चाहता हूँ कि एसई पर सभी जवाब था। एक समाधान और कुछ गहराई।
शैम्पू

4

महान समाधान। हो सकता है कि किसी को वही समस्या हो जो हमारे पास थी, इसलिए मैं एक और संभावित समाधान पोस्ट करूंगा। हमारे मामले में हमारे पास एक संग्रह था, जिसमें कभी-कभी बयान द्वारा एक समूह शामिल होता था और कभी-कभी यह ग्रिड के आधार पर नहीं होता था जहां संग्रह लोड किया गया था। उपरोक्त समाधान का उपयोग करते हुए, हमें दो समस्याएं मिलीं:

  1. यदि संग्रह खाली है, तो आकार का मान 1 है, हालांकि यह शून्य होना चाहिए।
  2. उन मामलों में जहां संग्रह पर स्टेटमेंट द्वारा समूह के बिना getSize विधि को बुलाया गया था, आकार को 1 आइटम के रूप में महत्व दिया जाता है, भले ही संग्रह में कितने आइटम हों।

डिबगिंग के थोड़ी देर बाद हमें पता चला, कि मामले में 1 हिस्सा है

$this->getConnection()->fetchall( $sql, $this->_bindParams ) 

एक सरणी देता है जिसमें मान के साथ एक प्रविष्टि है 0. यही कारण है कि गिनती फ़ंक्शन 1 रिटर्न करता है, हालांकि कोई प्रविष्टि नहीं मिली।

मामले में 2 एक ही हिस्सा एक प्रविष्टि के साथ एक सरणी देता है, जिसका मूल्य संग्रह का वास्तविक आकार है। गणना फ़ंक्शन फिर से 1 लौटाता है न कि मान।

एक विकल्प की खोज करते हुए, हमें पता चला कि उत्पाद संग्रह फ़ंक्शन reSelectCountSql () का पुनर्लेखन करता है। हमने इसे अनुकूलित किया और इसे थोड़ा बदल दिया, जो इस समाधान में समाप्त हो गया:

public function getSelectCountSql()
{
    $countSelect = parent::getSelectCountSql();
    $countSelect->reset(Zend_Db_Select::COLUMNS);
    $countSelect->reset(Zend_Db_Select::GROUP);
    $countSelect->columns('COUNT(DISTINCT item_id)');

    return $countSelect;
}

यह उन दो मुद्दों को हल करता है जिनका मैंने पहले ही उल्लेख किया है और जहां तक ​​मैं देख सकता हूं, यह अन्य मामलों के लिए भी काम करता है।


उत्पाद संग्रह मॉडल का संदर्भ देने के लिए धन्यवाद। इसने मेरी मदद की।
दिनेश यादव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.