tags:

views:

587

answers:

4

Hi,

I have a Projects table and a Users table which are linked by a HABTM relation. In the "add" new Project page I have a multiple checkbox section to select Users for the new project. I want to have at least one User for the Project. What's the best way to approach this in CakePHP ?

A: 

To make this initial setup ridiculously easy you should take a look at Cakes naming conventions and then use the Cake Bake console app to build your scaffolding then modify from there.

This will literally save you hours of work.

But to answer your question, you would need some sort of validation on the other side of the form submission to check that there is at least one selected. There are many built in Cake validation methods however this is a very simple problem so I would probably just use basic PHP in the model to check.

Thanks for your quick answer. I use console to bake my initial models with validation but I didn't find anything in the docs for HABTM validation. I was wondering if Cakephp had a simple way of doing this. I'll try with the beforeValidation or a custom validation on my Project model.
Sabourinov
+1  A: 

teknoid's blog has a pretty in depth solution to your issue here. The most Cakey way of doing this would be to add custom validation to your model, as you mention in your comment above. Check out http://teknoid.wordpress.com/2008/10/16/how-to-validate-habtm-data/

From the article, where Tag HABTM Post (:: Project HABTM Users):

First, we validate the Tag model, by using the data from the form to ensure that at least one Tag was selected. If so, we save the Post and the relevant Tags.

Travis Leleu
+5  A: 

Try this:

// app/models/project.php
/**
 * An additional validation check to ensure at least one User is
 * selected. Spoofs Cake into thinking that there are validation
 * errors on the Project model by invalidating a non-existent field
 * on the Project model, then also invalidates the habtm field as
 * well, so when the form is re-displayed, the error is displayed
 * on the User field.
 **/
function beforeValidate() {
  if (!isset($this->data['User']['User'])
  || empty($this->data['User']['User'])) {
    $this->invalidate('non_existent_field'); // fake validation error on Project
    $this->User->invalidate('User', 'Please select at least one user');
  }
  return true;
}
neilcrookes
Perfect! Thanks Neil.
Sabourinov
+2  A: 

I've just been looking at his problem myself on a project and came across a slightly more elegant solution, as long as you're only dealing with a habtm relationship and you need to ensure that at least one checkbox is selected.

so for example you're editing a Project and you want it to be associated with at least one user

Add this to beforeValidate()

// check habtm model and add to data

  foreach($this->hasAndBelongsToMany as $k=>$v) {
   if(isset($this->data[$k][$k]))
   {
    $this->data[$this->alias][$k] = $this->data[$k][$k];
   }
  }

In the validation rules add the following:

'User' => array(
   'rule' => array('multiple', array('min' => 1)),
   'message' => 'Please select one or more users'
  )