CakePHP continues to amaze me. There’s a new feature every time I turn around! Yesterday I experimented with something, and found that it worked. I couldn’t find documentation of it anywhere, so decided to write it down.
If you’ve got a model association defined in your model, you can change it on the fly from your controller.
For example, I’ve got Events and Registrants. Registrants can sign up for an event in step 1, and pay in step 2. At the end of step 1, the registrant is entered into the table as not_yet_paid (paid=0), and at the end of step 2, their row is marked as fully_paid (paid=1). But some people quit after step 1, without completing step 2. When reviewing event sign-up statistics, the client wants, understandably, to be able to separate out those who completed the process from those who didn’t. (Sometimes, if you send a prompt to someone who started but didn’t finish, they will come back and pay, so it’s worth keeping the data rather than just throwing it out.)
The association in my Event model looks like this:
var $hasMany = array( 'Registrant' => array( 'className' => 'Registrant', 'foreignKey' => 'event_id', 'dependent' => false, 'conditions' => 'Registrant.paid = 1', ), );
Now in my controller, I check for a variable set in the URL by the client user when viewing statistics, and decide based on that whether to change the ‘conditions’:
if ($showunpaid=='unpaidtoo') $this->Event->hasMany['Registrant']['conditions'] = null; else if ($showunpaid=='unpaidonly') $this->Event->hasMany['Registrant']['conditions'] = "Registrant.paid = 0";
This way, registered-but-unpaid registrants are never counted and never show up by default, but that can be changed easily from any controller.
Gotta love cake.