3 votes

Utilisation de champs booléens avec Magento ORM

Je travaille sur une page d'édition en arrière-plan pour mon entité personnalisée. J'ai presque tout fait fonctionner, y compris l'enregistrement d'un certain nombre de champs de texte différents. J'ai cependant un problème lorsque j'essaie de définir la valeur d'un champ booléen.

J'ai essayé :

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

Aucun ne semble persister un changement dans ma base de données.

Comment définir un champ booléen en utilisant l'ORM de Magento ?

modifier En regardant ma base de données, mysql stocke le champ comme un tinyint(1), donc magento peut le voir comme un int et non un bool. Mais je n'arrive toujours pas à le définir.

6voto

ivantedja Points 2543

Ce sujet a suscité ma curiosité. Bien qu'il ait été répondu, j'aimerais partager ce que j'ai trouvé, bien que je n'aie pas fait de recherches intenses.

Peu importe que le cache soit activé ou désactivé, le schéma de la table sera mis en cache.

Il sera mis en cache pendant le processus de sauvegarde.

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;
}

Voir la ligne : $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;
}

Comme on peut le voir :

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

va essayer de charger le schéma à partir du cache.

Si la valeur n'existe pas : if ($ddl === false)

il en créera un : $this->saveDdlCache($cacheKey, self::DDL_DESCRIBE, $ddl);

Ainsi, le problème rencontré dans cette question se produira si nous sauvegardons un jour le modèle qui va être modifié (ajout de colonne, etc.).

Parce que ça a toujours été $model->save() le schéma sera mis en cache. Plus tard, après l'ajout d'une nouvelle colonne et la sauvegarde, le schéma sera chargé à partir du cache (qui ne contient pas la nouvelle colonne) et le résultat sera le suivant : les données de la nouvelle colonne n'ont pas été sauvegardées dans la base de données.

5voto

kalenjordan Points 1004

Supprimez var/cache/* - votre schéma de base de données est mis en cache par Magento même si la nouvelle colonne est déjà ajoutée à la table MySQL.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X