No body is insured from stupid mistakes while writing code. I am not insured, but subscribed for such things. π
Here is the story:
Yesterday, while I was working for a small project I lost 1 hour to detect the stupidest mistake I ever made. Here I will explain what happened and how dummy I fee after that.
I am writing an application where users insert records into the database, and after that on every show of the record, there is a counter field which need to add up the number in it. Simple and easy situation.
While I was working I noticed that only one record /from 5 in the database/ got updates on his counter fields. All other had 0, while I was petty much sure that I’ve seen all these records on the screen. Well, I forced showing the 0 rows but the result was the same. Then I start investigating what could be the problem, but in the database everything was just fine. I deleted all records and started inserting texts /because there are some text fields important in this story/ one by one. Strangely, but again some of the records got update, some not. Finally /by accident/ I noticed, that counter changes when there is a space before or in the end of the value of the text I entered.
It was the strangest situation I ever seen while using CakePHP, I even thought that I catch the biggest bug I’ve ever seen.
And then the thunder hit my brain – d’oh, how stupid am I. π
So, the explanation of the problem was really obvious, but until you don’t see it it’s really mysterious behavior. π Because I wanted only unique records in the database, I’ve set a small function in the Model class which check if these text fields are unique.
$count = $this->find('count', array(
'conditions'=>array(
'text1 LIKE'=>trim($data['Record']['text1']),
'text2 LIKE'=>trim($data['Record']['text2']),
'text3 LIKE'=>trim($data['Record']['text3']),
'type_id'=>$data['Record']['type_id']
)
));
if($count > 0){
return false;
} else {
return true;
}
}
function beforeSave(){
return $this->checkUniques($this->data);
}
As you may see I am checking if there is already same row in the database and if there is the script returning false. The trick is that this function need to execute only when it’s an insert action, because otherwise of course the record exists and the function will return me false, but why some records add up some not. Well, this was the catch – I am checking trim()-ed version of the values, while in the database they were with space and this way it was possible to say they are unique.
Well, at least there is an idea coming from this situation: I think it’s good to have 2 additional functions in top of beforeSave() function and they should be beforeInsert() and beforeUpdate() – the functionality will be very simple – if beforeInsert or beforeUpdate return false, then also beforeSave will return false as well. This could give flexibility to use all of them – if you want to distinguish insert or update – use these new ones, of you want to cover both cases, you can use only beforeSave() and so on.
Anyway, I will post this as proposal in the trac.cakephp.org, hoping the development team to implement it in the future release /who knows probably even in the stable version of CakePHP 1.2 π
Pingback: write wp application
Bummer. π
hmmm nice idea. wondered about writing and publishing a behavior allowing this functionality ? – for example models could “actAs” “extendible” or some name like that …
to be honest I my self haven’t wrote a behavior yet, but I love the idea / concept and this is pretty much doable through a behavior. besides, this would make it much easier to be thrown into cake’s core library …
aha ! may be I can beat you to it π {provided I find the time soon enough π }
SayB, In fact I’ve proposed this solution to CakePHP developers, but they argued because this is most likely problem of the validation process, rather than saving functionality and I agree with them.
This one could be done easily if you use ‘on’ in the validation rule “on” could have 2 possible values: “create” or “update” and using isUnique rule which is already build in make writing additional code for this case Useless.
In another hand, if there is real beforeSave case, where for example the logic need save something in third table for example not related with the primary one and this need to be done on create of course, then I think the problem still exist.
Anyway, so far I think there is a solution for this, so I will leave this without any further activity π
This one could be done easily if you use βonβ in the validation rule βonβ could have 2 possible values: βcreateβ or βupdateβ and using isUnique rule which is already build in make writing additional code for this case Useless.