I am developing a custom Magento module that needs to save a list of email addresses into a custom table. The relevant code looks like this:
foreach($this->getNewSubscriptionsForAPI() as $email){
$requestModel->setEmail($email);
$requestModel->setAction('subscribe');
$requestModel->setPosted(date('Y-m-d H:i:s'));
$requestModel->save();
}
The getNewSubscriptionsForAPI()
method is returning valid data, and the $requestModel
is a valid Magento model.
When this loop runs, however, the database adaptor simple overwrites each record on top of the previous one. Ie, if I repeatedly hit 'browse' in phpMyAdmin I can see different email addresses being written to the database but always in the same row, overwriting the previous entry. The id field is correctly set up: as primary key, set to AUTO_INCREMENT, and flagged as the id field in the resource model.
What's interesting is that I can use the loop above to write successive records in the core newsletter/subscriber
table with no problem.
I could, of course, simply unset()
the model and get it back out of the Mage::getModel()
at each cycle of the loop, but this (a) seems hugely wasteful, and (b) spoils my Dependency Injection setup for testing (where I don't want the code to be instantiating its own models, but using the ones I pass to it).
Can anyone point me in the right direction?
When Magento saves a new object it automatically generates an id for the object. After you have saved the object hence an id is generated. To make magento recognize your data as a new model again, you simply need to unset the model id
. I think however unsetData
is more elegant as it also erases any data that might have been created for the previous object :-).
Ah, it seems like I may have answered my own question. By including a call to $requestModel->unsetData();
just after the call to $requestModel->save()
the loop works as intended.
unsetData
is a method made available by Varien_Object, which Mage_Core_Model_Abstract inherits from.
I'm happy for someone to contribute a more elegant solution I'm happy to hear it.
I don't know if this is more elegant or not but managed to solve your problem with this code. At each loop a new row will be added with the new information.
foreach($this->getNewSubscriptionsForAPI() as $email){
$data = array('email' => $email, 'action' => 'subscribe',
'posted' => date('Y-m-d H:i:s');
$requestModel->setData($data)->save();
}
Considering 'email', 'action' and 'posted' are your database table’s field names.
This is an old thread, but for anyone coming across this, while the unsetData()advice is correct, the fact that this method calls the save() function inside a loop is bad practice and will definitely slow your site down.
You can write a function in the ResourceModel of your Model structure to allow adding multiple items inside a transaction which will be much safer as well as increase performance exponentially.
See Here and Here for some better ideas.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With