"Why oh why won’t CakePHP store my tinyint(1) data?" #2

Mijn god wat heeft me dit zitten irriteren. Cake wilde mijn tinyint(1) veld niet opslaan. Zolang het veld 0 was, was het oké. Alles groter dan 0 werd een één. Na een beetje zoeken op internet kwam ik een artikeltje tegen die me op weg hielp, maar niet met een oplossing kwam zoals ik had gehoopt. Daarom dit vervolg.

Scott Anderson, schreef op zijn blog al eerder over:

MySQL is a pretty cool database. I’m very loyal to it. But there are some things it should do, but it just doesn’t. One of those things is support a boolean data type. So, we make do. A common way to make do, and the way preferred by CakePHP, is to use a tinyint(1) field and just store 0 or 1 in it. In fact, CakePHP loves this approach so much that whenever it sees a data field that’s a tinyint(1), it “automagically” refuses to accept any values for that field other than 0 or 1.

Oplossingen volgens Scott

Zoals hij zegt is dat natuurlijk helemaal top, behalve als je 'gewoon' iets op wilt slaan in een tinyint(1) veld. Scott geeft als oplossing dat je kunt kiezen om het veld om te zetten in een char(1) of een tinyint(2). Uiteraard was dat niet de oplossing die ik zocht.

Een andere oplossing, volgens Bjorn

Cake verzamelt alle informatie over een tabel met de schema() functie, in de Model class. Omdat een gewoon Model via AppModel weer Model extend, is het mogelijk om deze te overschrijven. En dat is dus ook wat ik deed.

var $_schemaAddition = array(
    'status' => array(
        'type' => 'integer',
        'length' => 1,
        'default' => 1,
        'null' => false,
    ),
);

/**
 * Adds a 'overwrite' functionality to schema().
 *
 * @param string $field 
 * @return void
 * @author Bjorn Post
 */
function schema($field = false)
{
    $db =& ConnectionManager::getDataSource($this->useDbConfig);
    $db->cacheSources = ($this->cacheSources && $db->cacheSources);
    if($db->isInterfaceSupported('describe'))
    {
        $this->_schema = array_merge($db->describe($this, $field), $this->_schemaAddition);
    }

    return parent::schema();
}

Ik heb schema() zo uitgebreid, dat er de mogelijkheid ontstaat om keys te overschrijven met je eigen data. Zo overrule je dus de automagische aanname van Cake dat ieder tinyint(1) veld een boolean is.

Ohja, vergeet /app/tmp/cache/ daarna niet leeg te gooien, Cake cached de describes.


Reacties

Er zijn op dit moment geen reacties.