Key/value tables and how to use them in CakePHP 1.3

The key/value tables (EAV model) are a nice a approach to database modeling, when we need to store some arbitrary data about another model. For example, let’s take a User model. We could create a single users table to hold all of the potential data or even create an additional table such as user_details with all additional fields, which “might” be needed. However, what happens when we don’t exactly know how much or what data will be eventually required by the application? How many phones does the user have? Should we create a table with fields phone1, phone2, phone3, etc.? What about emails? (Some users have 1 some have 5) What happens if the business later on decides to ask for a fax number?.. and person’s height or favorite color? If we attempt to predefine all the place-holders (columns or fields in a table) for the potential data, the table can grow horizontally into an unmanageable monster. This is the perfect time to enter key/value tables. Let’s consider our User model and, therefore the users table: [sourcecode language=”sql”] CREATE TABLE `users` ( `id` char(36) COLLATE utf8_unicode_ci NOT NULL DEFAULT ”, `username` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `password` varchar(255) COLLATE …

January 2009

JQuery in the CakePHP world (part 2 – is client side code all that great?)

(part 1) Now, how is this an introduction to jQuery + CakePHP?… well, let’s see in a minute. First, I’d like to say that with the advent of frameworks such as jQuery, better browsers, which do a nicer job of supporting standards, and even faster PC’s and larger/better monitors, we can happily write better client-side code. Meaning the following rules are slightly not as important anymore: A client’s browser may not support my code A client is not fast enough to process the code A client is never to be trusted While the first two rules are becoming less and less applicable, the third one stays true for a while (and for a good reason). Where does it come into play? For purposes of this topic, and I can imagine many other cases, where it would be true, we’ll say “Data Validation”. Indeed, if you validate data on the client-side only, you are running into a serious risk of getting some “really bad” data. So, always double-check the data on the server (that’s a rule that should rarely be bent). The good news is that nothing is stopping us from doing data validation on the client, the server and …

November 2008

'required'=>true… the source of major confusion

In all the time I’ve been following cake on IRC (almost daily), it has become very clear that other than ACL and maybe Auth, ‘required’=>true in the model validation is the most confusing part of CakePHP for many people. On IRC it comes up, probably, once a week… even from people who’ve “been around”. And I can imagine that there are a lot of apps out there, where ‘required’=>true is used, without fully understanding as to what it really does. The problem is that people are quick to assume that ‘required’ means ‘notEmpty’. Even after pointing people to RTFM, they still come back confused as to the real meaning of ‘required’. Who cares, right? Well… we often hear a complain about save() failing (very often) without any apparent reason. The issue boils down to people having ‘required’=>true in the validation rules, while in reality they only wanted ‘rule’=>’notEmpty’. When first creating the Model such setup has no ill effects, because all fields are in the data array and the record can be successfully added and even edited (assuming some basic forms). Then at some point the app becomes a little more complex and people decide to save only a few …

'required'=>true… the source of major confusion

In all the time I’ve been following cake on IRC (almost daily), it has become very clear that other than ACL and maybe Auth, ‘required’=>true in the model validation is the most confusing part of CakePHP for many people. On IRC it comes up, probably, once a week… even from people who’ve “been around”. And I can imagine that there are a lot of apps out there, where ‘required’=>true is used, without fully understanding as to what it really does. The problem is that people are quick to assume that ‘required’ means ‘notEmpty’. Even after pointing people to RTFM, they still come back confused as to the real meaning of ‘required’. Who cares, right? Well… we often hear a complain about save() failing (very often) without any apparent reason. The issue boils down to people having ‘required’=>true in the validation rules, while in reality they only wanted ‘rule’=>’notEmpty’. When first creating the Model such setup has no ill effects, because all fields are in the data array and the record can be successfully added and even edited (assuming some basic forms). Then at some point the app becomes a little more complex and people decide to save only a few …

September 2008

Set::merge() and dynamic validation rules

Here’s another trick with Set::merge()… Let’s say we’ve defined some basic validation rules in our Profile model, something like: var $validate = array (    ‘name’ => array(       ‘rule’ => array(’notEmpty’),       ‘required’ => false,       ‘message’ => ‘Please enter a name’      )   …. and so on for all other fields … ); Now we’ve got an action where this particular set of rules isn’t going to fly… Maybe the data is coming from an external (somewhat untrusted) source and in this case we need to make sure that the ‘name’ is present in the data array (i.e. ‘required’=>true) and that it’s not only ‘notEmpty’, but now it has to be ‘alphaNumeric’. So we do an easy “update” to our default rules, which we’ve previously defined in the model: $this->Profile->validate = Set::merge($this->Profile->validate, array(       ‘name’=>array(          ‘required’=>true,          ‘rule’=>array(’alphaNumeric’)       ) )); What happened is that now all our default rules remain as we have defined them in the model, but the ‘name’ field is now going to be validated using this new set …

July 2008

notEmpty validation rule

With the recent changeset (https://trac.cakephp.org/changeset/7399) a new, ‘notEmpty’, validation rule is now available. As you can guess, it checks to make sure that a field contains something other than a white space. You will have to upgrade to the latest build, to ensure that this rule is available in your cake core. Otherwise you can rely on this simple regex, to achieve the same thing: ‘rule’ => array(’custom’, ‘/\S+/’)

June 2008

Validating a checkbox in CakePHP 1.2

In a few simple words: use the ‘comparison’ rule to validate a checkbox. To give you an example, let’s say a user needs to agree to the terms of service when registering a new account. In your User model you setup a rule for the checkbox as follows:  ‘agree’ => array(               ‘rule’ => array(’comparison’, ‘!=’, 0),               ‘required’ => true,               ‘message’ => ‘You must agree to the terms of use’,                 ‘on’ => ‘create’        ) As you can probably guess from the code the empty checkbox will send a default value of zero, and that is what your validation rule is going catch. The ‘on’ key will ensure that the rule is only enforced on account creation and not when the User is editing an existing account.

15 Essential CakePHP Tips

Note, this article was written a long time ago for CakePHP version 1.x … many of the points described here still apply in the latest 2.x versions of CakePHP. 1. Save() does not work! Sometimes it happens that save() fails without any obvious reason. Your data array looks fine and you’ve build the form correctly, etc., etc., but no query was executed. It is very possible that save had failed due to validation errors. Maybe you are updating some model and while the current fields in the form pass the validation, there is a chance that some “other ones” are causing the validation rules to fail. An easy (and helpful) way to see what’s going on with validation is to do pr($this->validationErrors); in your view. By employing this method you’ll see exactly what’s happening with your model’s validation. The other option is to pass false as a second parameter to save(); in order to disable the validation. However, the latter method does not give much of hint and should not be used to fix a failing problem, but rather to purposely avoid validation. 2. Save() still does not work! Do you have beforeSave(); in your model or app model? …

May 2008

Do I have any errors in my form?

A nice little trick to check if you have some errors in the view is to use the $session object. Try this (in the view): pr($this->validationErrors) or pr($session->validationErrors), be sure to actually have some errors in the form… I leave it up to you to come with some nice usage for it. Well, here’s a little hint: try creating an element that will check if the above array is empty or set, and if so display some generic message, such as “Please fix the errors below…” this is especially useful for long HTML forms where the actual error message (or field error) might fall below the screen fold.