Kohana 3.1 ORM: Empty model property value saved as 0 (zero) instead of NULL
I have two models, Product and Product_Methodology. In my product edit view I have a select form field to select one of many methodologies or none (empty first option). In my products table I have a INT(10)
methodology_id
property that gets saved with the id of the methodology selected from the select form field. Everything worked OK until today that I had to make an adjustment to the system in which since now selecting a methodology can be optional. So I changed the methodology_id
field of the products table to allow NULL
value and removed the not_empty
validation rule on the model.
The prob开发者_开发百科lem is that now when I save the model selecting the empty option, instead of the expected NULL
, I get a 0
(zero) value.
Any clue on this? Thanks a lot and let me know if it's not so clear.
What form input are you using for choosing the methodology? is it <select>
?
If so, the value of choosen option is probably set to 0 when no methodology is choosen, and send with other form data.
In such cases I make a custom filter withing model's filters()
method, to set the value to NULL (as PHP treats it) when it's empty()
, something like this:
public function filters()
{
return array(
'methodology_id' => array(
array('Filter::null', array(':value')),
),
);
}
Where Filter is helper class with static methods. like...:
class Kohana_Filter {
public static function null($value)
{
return (empty($value) ? NULL : $value);
}
}
Hope this helps :)
Even if the submitted form field is blank it's a string with any empty value - not NULL. This gets cast as 0 when saved to an INT field (at least in mysql). To preserve a null value do something like this:
$methodology_id = (empty($methodology_id) ? NULL : $methodology_id);
An example of using a closure to return a NULL value if the field value is an empty string:
public function filters()
{
return array(
// Return a NULL value if empty string.
'field_name' => array(
array(function($value){
return ($value === '') ? NULL : $value;
}, array(':value')),
)
);
}
What you should do is set the key for the None value in your select box to 0.
You should leave the not_empty rule for the field. Then you should have a rule for the field that makes sure that the value is either a legitimate value for product_methodology or zero.
I extend ORM and have the following two functions:
public function exists_or_zero(Validation $validation, $field, $model, $pk)
{
// The exists() function is only called if the field has a non-zero value
if ($validation[$field]) {
$this->exists($validation, $field, $model, $pk);
}
}
public function exists(Validation $validation, $field, $model, $pk)
{
if ( ! ORM::factory($model, $pk)->loaded()) {
$validation->error($field, 'exists', array($validation[$field]));
}
}
If you were to use these functions, you're rules in the product class would look like:
public function rules()
return array(
'product_methodology_id' => array(
array('not_empty'),
array(array($this, 'exists_or_zero'), array(':validation', ':field', 'product_methodology', ':value')),
),
);
}
精彩评论