1

I am currently going through and optimizing our codebase for our custom modules. I am using PHP Codesniffer along with the Magento Coding Standard rules to scan our code.

In many of our files I see a warning like

Model LSD method save() detected in loop

Here is an example of a function containing that error

public function resetmasstatusAction()
 {
    $invoicesIds = $this->getRequest()->getPost('invoice_ids');
    if (!empty($invoicesIds)) {
        $invoices = Mage::getResourceModel('sales/order_invoice_collection')
            ->addAttributeToSelect('*')
            ->addAttributeToFilter('entity_id', array('in' => $invoicesIds))
            ->load();
        foreach ($invoices as $invoice) :
            $invoice->setMas_status('NEW')
                ->setMas_updated_at(date('Y-m-d H:i:s'))
                ->save();
        endforeach;
    }
    $this->_redirect('*/sales_invoice/index');
}

How would I go about doing the save operation for all items in a collection such as this one, without having the save() function in the foreach loop to improve performance?

2

After doing some research into this, I discovered that the best way to do this is like the following.

Please note that the walk iterator is essentially the same thing as a foreach loop, however the goal in my original question was how to not run a SQL query over and over again in a foreach loop.

By running the save() function on the entire $invoices object, we essentially run a large SQL query to save all of the rows at once rather than running a bunch of small queries.

public function resetmasstatusAction()
 {
    $invoicesIds = $this->getRequest()->getPost('invoice_ids');
    if (!empty($invoicesIds)) {
        $invoices = Mage::getResourceModel('sales/order_invoice_collection')
            ->addAttributeToSelect('*')
            ->addAttributeToFilter('entity_id', array('in' => $invoicesIds))
            ->load();
        //The below will allow you to save the updated collection
        //Without running multiple SQL queries in the foreach loop.
        $invoices->walk('setMas_status', array('NEW');
        $invoices->walk('setMas_updated_at', array(date('Y-m-d H:i:s'));           
        $invoices->save();
    }
    $this->_redirect('*/sales_invoice/index');
}
  • 1
    The save method from the 'sales/order_invoice_collection' is defined in Mage_Core_Model_Resource_Db_Collection_Abstract, where it actually does a foreach to save each item. – Cladiuss May 30 '17 at 15:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.