9

我正在开发一个自定义 Magento 模块,该模块需要将电子邮件地址列表保存到自定义表中。相关代码如下所示:

foreach($this->getNewSubscriptionsForAPI() as $email){
            $requestModel->setEmail($email);
            $requestModel->setAction('subscribe');
            $requestModel->setPosted(date('Y-m-d H:i:s'));
            $requestModel->save();
        }

getNewSubscriptionsForAPI()方法返回有效数据,并且$requestModel是有效的 Magento 模型。

然而,当这个循环运行时,数据库适配器简单地将每条记录覆盖到前一条记录之上。即,如果我在 phpMyAdmin 中反复点击“浏览”,我可以看到不同的电子邮件地址被写入数据库,但总是在同一行中,从而覆盖先前的条目。id 字段设置正确:作为主键,设置为 AUTO_INCREMENT,并在资源模型中标记为 id 字段。

有趣的是,我可以使用上面的循环在核心newsletter/subscriber表中写入连续的记录,没有问题。

当然,我可以简单地unset()建立模型并将其从Mage::getModel()循环的每个循环中取出,但这(a)似乎非常浪费,并且(b)破坏了我的依赖注入设置以进行测试(我不希望代码实例化自己的模型,但使用我传递给它的模型)。

谁能指出我正确的方向?

4

4 回答 4

16

当 Magento 保存一个新对象时,它会自动为该对象生成一个 id。保存对象后,将生成一个 id。要让 magento 再次将您的数据识别为新模型,您只需取消设置模型即可id。然而,我认为unsetData更优雅,因为它还会删除可能为前一个对象创建的任何数据:-)。

于 2012-05-29T15:29:35.467 回答
8

啊,看来我可能已经回答了我自己的问题。通过在对循环$requestModel->unsetData();的调用之后包含对的调用,可以按预期工作。$requestModel->save()

unsetData是 Varien_Object 提供的一种方法,Mage_Core_Model_Abstract 继承自该方法。

我很高兴有人提供更优雅的解决方案,我很高兴听到它。

于 2012-05-29T11:05:22.710 回答
2

我不知道这是否更优雅,但设法用这段代码解决了你的问题。在每个循环中,都会添加一个带有新信息的新行。

foreach($this->getNewSubscriptionsForAPI() as $email){
            $data = array('email' => $email, 'action' => 'subscribe', 
                   'posted' => date('Y-m-d H:i:s');
            $requestModel->setData($data)->save();
        }

考虑到“电子邮件”、“操作”和“已发布”是您的数据库表的字段名称。

于 2013-11-12T11:57:20.860 回答
1

这是一个旧线程,但对于遇到此问题的任何人来说,虽然 unsetData() 建议是正确的,但此方法在循环内调用 save() 函数的事实是不好的做法,并且肯定会减慢您的网站速度。

您可以在模型结构的 ResourceModel 中编写一个函数,以允许在事务中添加多个项目,这将更加安全并成倍提高性能。

有关一些更好的想法,请参见此处此处

于 2019-04-03T15:52:39.053 回答