使用 Magento ORM 的布尔字段
Posted
技术标签:
【中文标题】使用 Magento ORM 的布尔字段【英文标题】:Using boolean fields with Magento ORM 【发布时间】:2012-08-30 20:47:59 【问题描述】:我正在为我的自定义实体创建一个后端编辑页面。我几乎可以正常工作,包括保存一堆不同的文本字段。但是,在尝试设置布尔字段的值时,我遇到了问题。
我试过了:
$landingPage->setEnabled(1);
$landingPage->setEnabled(TRUE);
$landingPage->setEnabled(0);
$landingPage->setEnabled(FALSE);
似乎没有人对我的数据库进行更改。
您应该如何使用 magento ORM 设置布尔字段?
编辑 查看我的数据库,mysql 将该字段存储为 tinyint(1),因此 magento 可能将其视为 int 而不是 bool。不过还是无法设置。
【问题讨论】:
setEnabled() 看起来像一个可能不仅仅是常规设置器的函数,你确定是吗?另外,如果这是一个新创建的字段,请务必删除整个 var/cache/ 目录 已启用是我的字段名称。不过,这可能是保留字问题,请对此进行测试。所有缓存都已关闭。 只是我身边的旁注。如果字段是新创建的并且您没有清除缓存,则保存它们时可能还会遇到一些问题,因为在缓存中 Magento / Zend Framework 保留了一些有关数据库的信息……例如表列等。Magento 还保留一些缓存,即使缓存被禁用! 用不同的字段名尝试过,没有运气。 @ceckoslab - 禁用缓存时保留哪些缓存?对 OP:您的列类型到底是什么?将 (bool) true 表示为 (int) 1 是 php 和 MySQL 长期以来一直在做的事情。 【参考方案1】:这个话题让我产生了好奇心。虽然已经回答了,但我想分享一下我没有进行深入追踪的发现。
不管是否启用/禁用缓存,表模式都会被缓存。
在保存过程中会被缓存。
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);
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()
,所以架构将被缓存。
稍后在他添加新列并“保存”后,它将从缓存中加载模式(不包含新列)并导致:新列的数据未能保存在数据库中
【讨论】:
【参考方案2】:删除 var/cache/* - 即使新列已添加到 MySQL 表中,Magento 也会缓存您的 DB 模式。
【讨论】:
以上是关于使用 Magento ORM 的布尔字段的主要内容,如果未能解决你的问题,请参考以下文章
自定义模块的自定义布局不会在 Magento 1.9 中加载