使用布尔字段与Magento ORM

3

我正在为自定义实体工作的后端编辑页面上进行开发,几乎所有功能都已经实现,包括保存多个不同文本字段。但是,当我尝试设置布尔字段的值时,遇到了问题。

我尝试过:

$landingPage->setEnabled(1);
$landingPage->setEnabled(TRUE);
$landingPage->setEnabled(0);
$landingPage->setEnabled(FALSE);

似乎没有将更改持久化到我的数据库中。

您应该如何使用Magento ORM设置布尔字段?

编辑 查看我的数据库,MySQL将该字段存储为tinyint(1),因此Magento可能将其视为int而不是bool。尽管如此,仍然无法进行设置。


setEnabled() 看起来不像是一个普通的 setter 函数,你确定它是吗?此外,如果这是一个新创建的字段,请确保删除整个 var/cache/ 目录。 - kalenjordan
Enabled是我的字段名称。可能是保留字问题,我会测试一下。所有缓存都已关闭。 - MrGlass
这只是我的一点小建议。如果这些字段是新创建的,并且您没有清除缓存,那么在保存它们时可能会遇到一些问题,因为Magento / Zend Framework在缓存中保留了有关数据库的某些信息...例如表列等。即使缓存已禁用,Magento也会保留一些缓存! - ceckoslab
1
尝试使用不同的字段名称,但没有成功。 - MrGlass
@benmarks 睡觉前的一些检查 :) 我检查了 var/cache/mage--6 中的一些文件,以及在文件 mage---6f8_DB_PDO_MYSQL_DDL_customer_eav_attribute_1 中发现了序列化数据,其中包含有关表结构的信息:https://gist.github.com/3544634 ... 如果我们使用 Flush Magento Cache,则模式文件不会被清除,但如果我们使用 Flush Cache Storage,则它们会被清除。也许明天早上我可以更深入地了解这些文件是如何读取的。 - ceckoslab
显示剩余8条评论
2个回答

6
这个话题引起了我的好奇心。虽然已经有答案了,但我想分享一下我发现的东西,尽管我没有进行深入追踪。
无论缓存是否启用/禁用,表模式都会被缓存。
在保存过程中,它将被缓存。
Mage_Core_Model_Abstract -> save()
Mage_Core_Model_Resource_Db_Abstract -> save(Mage_Core_Model_Abstract $object)
Mage_Core_Model_Resource_Db_Abstract

public function save(Mage_Core_Model_Abstract $object)
{
    ...
    //any conditional will eventually call for:
    $this->_prepareDataForSave($object);
    ...
}

protected function _prepareDataForSave(Mage_Core_Model_Abstract $object)
{
    return $this->_prepareDataForTable($object, $this->getMainTable());
}

Mage_Core_Model_Resource_Abstract

protected function _prepareDataForTable(Varien_Object $object, $table)
{
    $data = array();
    $fields = $this->_getWriteAdapter()->describeTable($table);
    foreach (array_keys($fields) as $field) {
        if ($object->hasData($field)) {
            $fieldValue = $object->getData($field);
            if ($fieldValue instanceof Zend_Db_Expr) {
                $data[$field] = $fieldValue;
            } else {
                if (null !== $fieldValue) {
                    $fieldValue   = $this->_prepareTableValueForSave($fieldValue, $fields[$field]['DATA_TYPE']);
                    $data[$field] = $this->_getWriteAdapter()->prepareColumnValue($fields[$field], $fieldValue);
                } else if (!empty($fields[$field]['NULLABLE'])) {
                    $data[$field] = null;
                }
            }
        }
    }
    return $data;
}

请看这行代码:$fields = $this->_getWriteAdapter()->describeTable($table);

该行代码涉及 IT 技术。
Varien_Db_Adapter_Pdo_Mysql

public function describeTable($tableName, $schemaName = null)
{
    $cacheKey = $this->_getTableName($tableName, $schemaName);
    $ddl = $this->loadDdlCache($cacheKey, self::DDL_DESCRIBE);
    if ($ddl === false) {
        $ddl = parent::describeTable($tableName, $schemaName);
        /**
         * Remove bug in some MySQL versions, when int-column without default value is described as:
         * having default empty string value
         */
        $affected = array('tinyint', 'smallint', 'mediumint', 'int', 'bigint');
        foreach ($ddl as $key => $columnData) {
            if (($columnData['DEFAULT'] === '') && (array_search($columnData['DATA_TYPE'], $affected) !== FALSE)) {
                $ddl[$key]['DEFAULT'] = null;
            }
        }
        $this->saveDdlCache($cacheKey, self::DDL_DESCRIBE, $ddl);
    }

    return $ddl;
}

正如我们所看到的:

$ddl = $this->loadDdlCache($cacheKey, self::DDL_DESCRIBE);

将尝试从缓存中加载模式。

如果该值不存在:if ($ddl === false)

它将创建一个:$this->saveDdlCache($cacheKey, self::DDL_DESCRIBE, $ddl);

因此,如果我们曾经保存即将被更改(添加列等)的模型,则会发生本问题。

由于之前已经进行了$model->save(),所以模式将被缓存。 稍后在添加新列并“保存”后,它将从缓存中加载模式(其中不包含新列),结果为:无法将新列的数据保存到数据库中。


5

删除 var/cache/* - 即使新列已经添加到MySQL表中,Magento仍会缓存您的数据库模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接