Null Behavior

By Christian Winther aka "Jippi"
Problems with default NULL fields not being very NULL'ish ?
This is just a small script to make sure some values arent saved if they are supposed to be NULL in the database.

*** Updated ***
Added check on length of string, to avoid the 0 being caught as a nullable value.

Use


Model Class:

Download code <?php 
var $actsAs = array('Null' => array('file_id','parent_id'));
?>


Code



Model Class:

Download code <?php 
class NullBehavior extends ModelBehavior {
    var 
$settings = array();

    
/**
     * Enter description here...
     *
     * @param AppModel $model
     * @param unknown_type $config
     */
    
function setup(&$model$config = array() )
    {
        
$this->settings$model->name ] = $config;
    }

    
/**
     * Enter description here...
     *
     * @param AppModel $model
     */
    
function beforeSave(&$model)
    {
        
$config $this->settings[$model->name];

        foreach ( 
$config AS $field )
        {
            if(
                
true === array_key_exists($field,$model->data[$model->name] ) &&
                
true === empty( $model->data[$model->name][$field] ) &&
                
=== strlen$model->data[$model->name][$field] ) )
            {
                unset(
$model->data[$model->name][$field]);
            }
        }
        return 
true;
    }
}
?>

Comments 297

CakePHP team comments Author comments

Comment

1 Might fail to save a field with a 0 value

I faced a similar problem with the numeric values being set to 0 instead of null (cake 1.1).
I did something similar, but the test :
true === empty( $model->data[$model->name][$field] )

will be true if the value is set to 0 (string or numeric), therefore it might be impossible to save a field whose value is 0.

Adding the following in the test expression fixes this :

&& $model->data[$model->name][$field] != "0"


posted Sat, Mar 24th 2007, 13:15 by franck

Comment

2 save NULL fields

I often use select lists with "empty"=>true (which prepends an empty option to the list). If the field I'm trying to write to is an INT and also accepts a NULL value, Cake will try to insert an empty string (''). I made this tweak to the Null behaviour to fix that:

//unset($model->data[$model->name][$field]);
$model->data[$model->name][$field] = NULL;
posted Tue, Apr 3rd 2007, 10:58 by Bryan Buchs

Comment

3 A slightly different version

This code is meant to be included in your app_model.php or particular model.



    function beforeSave() {
        /**
         * Checks table metadata for fields which allows NULL and set the value
         * to NULL when they are empty
         * 
         * TODO: probably make this a behavior?
         */
        $tableInfo = $this->_tableInfo->get();
        foreach ($tableInfo as $field) {
            if ($field['null']) {
                if (isset($this->data[$this->name][$field['name']]) && $this->data[$this->name][$field['name']] === '') {
                    $this->data[$this->name][$field['name']] = null;
                }
            }
        }
        
        return true;
    }
posted Fri, May 25th 2007, 22:14 by Derick

Comment

4 That looks good

This code is meant to be included in your app_model.php or particular model.


Hey Derick, your code looks much more better.
posted Wed, Aug 8th 2007, 21:16 by Marton Sari

Comment

5 Updating Dericks Code

Derick's code needed a few tweaks to work on 1.2.0.6311 beta:

    function beforeSave() {
        /**
         * Checks table metadata for fields which allows NULL and set the value
         * to NULL when they are empty
         * 
         * TODO: probably make this a behavior?
         */
        $tableInfo = $this->schema();
        foreach ($tableInfo as $name => $field) {
            if ($field['null']) {
                if (isset($this->data[$this->name][$name]) && $this->data[$this->name][$name] === '') {
                    $this->data[$this->name][$name] = null;
                }
            }
        }
        
        return true;
    }
posted Sun, Apr 27th 2008, 08:44 by Peter Robinett

Login to Submit a Comment