how i can fetch user data in a manyToMany association - cakephp

I have a problem with CakePHP. I tested many ways, but can't find a solution for it.
I have these tables:
users
id
name
country_code
countries
code
title
skills
code
title
roles
id
title
events
id
title
country_code
events_users
event_id
user_id
role_id
skill_code
events hasAndBelongsToMany users and events_users is my join table, and when I read data, it gives me something like this:
array(
(int) 0 => array(
'Event' => array(
'id' => '1',
'title' => '40th WorldSkills Competitions',
'year' => '2011',
'country_code' => 'LV',
'created' => '2013-02-08 00:00:00'
),
'User' => array(
(int) 0 => array(
'password' => '*****',
'id' => '14',
'name' => 'test',
'family' => 'testian',
'username' => 'test#mail.me',
'country_code' => 'BR',
'telphone' => '465465',
'avatar' => 'avatar_51299c1da268f20110912043238_rodekamp_04.jpg',
'address' => 'AA',
'admin' => '0',
'created' => '2013-02-24 05:50:37',
'modified' => '2013-02-24 05:50:37',
'EventsUser' => array(
'id' => '1',
'user_id' => '14',
'event_id' => '1',
'role_id' => '1',
'skill_code' => '17',
'manage' => '100'
)
),
(int) 1 => array(
'password' => '*****',
'id' => '5',
'name' => 'John',
'family' => 'Smith',
'username' => 'john#me.com',
'country_code' => 'IE',
'telphone' => '147',
'avatar' => '20120504124040_franziska_peter_ok.jpg',
'address' => 'No 55',
'admin' => '0',
'created' => '2013-02-10 15:24:13',
'modified' => '2013-02-10 15:28:50',
'EventsUser' => array(
'id' => '2',
'user_id' => '5',
'event_id' => '1',
'role_id' => '2',
'skill_code' => '17',
'manage' => '0'
)
),
(int) 2 => array(
'password' => '*****',
'id' => '4',
'name' => 'hadi',
'family' => 'mm',
'username' => 'design.zerzem#gmail.com',
'country_code' => 'AE',
'telphone' => '415456',
'avatar' => '',
'address' => 'sadjfklsaf asd f',
'admin' => '0',
'created' => '2013-02-10 09:01:28',
'modified' => '2013-02-24 06:43:42',
'EventsUser' => array(
'id' => '3',
'user_id' => '4',
'event_id' => '1',
'role_id' => '4',
'skill_code' => '17',
'manage' => '0'
)
)
)
It's ok, but with events_users I want get data about skill and role that are in events_users (skill_code and role_id). How should I create models to give me all this data?

I think reading about "hasMany Through" should answer your question.
Basically, you make a model for your join table, then you can associate it like any other model.
When you go to retrieve your data, use CakePHP's Containable behavior (if you haven't used it before, be prepared to get addicted to it).

Related

recursive 2 with Cakephp functional

I need to build a select drop-down list from data from find().
When I perform a recursive find:
$parlamentarios = $this->Revocatorio->Parlamentario->find('all', array('recursive' => 2));
It returns the following:
array(
(int) 0 => array(
'Parlamentario' => array(
'id' => '1',
'postulacion_id' => '4',
'created' => '2016-01-10 20:29:47',
'periodo_id' => '1',
'voto_parlamento' => '4000'
),
'Postulacion' => array(
'id' => '4',
'registro_id' => '2',
'comite_id' => '5',
'periodo_id' => '1',
'fecha_elec' => '2016-01-23',
'created' => '2016-01-03 20:40:18',
'voto' => '0',
'Registro' => array(
'id' => '2',
'cedula' => '',
'nacionalidad' => '1',
'nombre' => '',
'seg_nombre' => '',
'apellido' => '',
'seg_apellido' => '',
'genero' => true,
'fecha_nac' => '-',
'lugar_nac' => 'Portuguesa',
'fecha_reg' => '2015-12-02',
'direccion' => 'aijhaoihdwaoih',
'edad' => '21',
'foto' => '1 LOGO UNERG.jpg',
'foto_dir' => '2',
'leer' => true,
'escribir' => true,
'discapacidad' => 'ninguna',
'aptitud' => true,
'estado_civil' => 'Casado/a',
'ccregistro_id' => '0',
'name' => ' - '
),
'Comite' => array(
'id' => '5',
'comite' => 'awdawdawdawd'
),
'Periodo' => array(
'id' => '1',
'periodo' => '2015-2017'
),
'Escrutinio' => array(),
'Revocatorio' => array()
),
'Periodo' => array(
'id' => '1',
'periodo' => '2015-2017',
'Ccregistro' => array(),
'Escrutinio' => array(),
'Postulacion' => array(
(int) 0 => array(
'id' => '2',
'registro_id' => '3',
'comite_id' => '3',
'periodo_id' => '1',
'fecha_elec' => '2015-12-24',
'created' => '2015-12-22 05:42:21',
'voto' => '200'
),
(int) 1 => array(
'id' => '3',
'registro_id' => '2',
'comite_id' => '1',
'periodo_id' => '1',
'fecha_elec' => '2016-01-20',
'created' => '2016-01-03 05:46:46',
'voto' => '0'
),
(int) 2 => array(
'id' => '4',
'registro_id' => '2',
'comite_id' => '5',
'periodo_id' => '1',
'fecha_elec' => '2016-01-23',
'created' => '2016-01-03 20:40:18',
'voto' => '0'
),
(int) 3 => array(
'id' => '5',
'registro_id' => '3',
'comite_id' => '9',
'periodo_id' => '1',
'fecha_elec' => '2016-01-21',
'created' => '2016-01-03 20:41:03',
'voto' => '0'
),
(int) 4 => array(
'id' => '6',
'registro_id' => '3',
'comite_id' => '11',
'periodo_id' => '1',
'fecha_elec' => '2016-01-14',
'created' => '2016-01-03 21:06:27',
'voto' => '0'
),
(int) 5 => array(
'id' => '7',
'registro_id' => '2',
'comite_id' => '1',
'periodo_id' => '1',
'fecha_elec' => '2016-01-22',
'created' => '2016-01-04 02:38:17',
'voto' => '0'
)
)
),
'Escrutinio' => array(),
'Revocatorio' => array()
),
The relationships are:
Revocatorio hasMany Parlamentario
Parlamentario hasMany Postulacion
Postulacion hasMany Registro
I need save the id of Parlamentario, but show Postulacion.Registro.name in add view. How can I accomplish this?
Try this:
$this->Parlamentario->find("list", array(
"fields" => array("Parlamentario.id", "Postulacion.Registro.name"),
"contain" => array("Postulacion.Registro")
)
);
Peace! xD

Associations: HasMany with a BelogsTo inside it

Hi I am trying out CakePHP 2.5 and created the blog from the tutorial.
I'm adding comments to blog posts, each comment has a user, but I can't seem to pull back the user information.
in my user model
public $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
'Post' => array(
'className' => 'Post',
'foreignKey' => 'user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
in my comments model
public $belongsTo = [
'User' => [
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
],
'Posts' => [
'className' => 'Posts',
'foreignKey' => 'post_id',
'conditions' => '',
'fields' => '',
'order' => ''
]
];
and in the postmodel, post being whenre I want to display the comment and the username
public $belongsTo = [
'User' => [
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
]
];
public $hasMany = [
'Comment' => [
'className' => 'Comment',
'order' => 'Comment.created DESC',
'foreignKey'=> 'post_id'
]
];
viewing a post brings back the following comment information
'Comment' =>
array (size=1)
0 =>
array (size=6)
'id' => string '1' (length=1)
'content' => string 'This is a comment' (length=17)
'created' => string '2015-10-23 15:59:55' (length=19)
'modified' => string '2015-10-23 15:59:55' (length=19)
'user_id' => string '1' (length=1)
'post_id' => string '2' (length=1)
But this doesn't include the user information as I expected.
My question is how do I pull the user information for each comment within a post
Sorry, I don't have points for commenting. Could you post your find() method? Also, do you have recursion turned on, or is it off (turned to -1) and you are using contain to grab associated models?

CakePHP bindTranslation() returns only records for current locale

I want to retrieve all records from the original table (category) with their translations from translation table (category_i18ns). I want all the records from the table category, regardless of my current locale settings.
Currently when I use bindTranslation(), it returns the all the records from the translation table, but only for the records (from table categories) that match the current locale.
Here is an example:
Records in table category_i18ns
id,created,modified,locale,model,foreign_key,field,content
1,"2014-08-15 17:08:26","2014-08-15 17:08:26",eng,Category,1,name,Entertainment
2,"2014-08-15 17:08:26","2014-08-15 17:08:26",eng,Category,1,url_name,entertainment
3,"2014-08-15 17:09:47","2014-08-15 17:09:47",eng,Category,2,name,Location
4,"2014-08-15 17:09:47","2014-08-15 17:09:47",eng,Category,2,url_name,location
5,"2014-08-15 17:12:11","2014-08-15 17:12:11",nld,Category,2,name,Locatie
6,"2014-08-15 17:12:11","2014-08-15 17:12:11",nld,Category,2,url_name,locatie
7,"2014-08-15 17:12:11","2014-08-15 17:12:11",nld,Category,3,name,Vervoer
8,"2014-08-15 17:12:11","2014-08-15 17:12:11",nld,Category,3,url_name,vervoer
9,"2014-08-15 17:12:11","2014-08-15 17:12:11",deu,Category,1,name,Unterhaltung
10,"2014-08-15 17:12:11","2014-08-15 17:12:11",deu,Category,1,url_name,unterhaltung
11,"2014-08-15 17:12:11","2014-08-15 17:12:11",nld,Category,1,name,Vermaak
12,"2014-08-15 17:12:11","2014-08-15 17:12:11",nld,Category,1,url_name,vermaak
13,"2014-08-15 17:12:11","2014-08-15 17:12:11",deu,Category,2,name,Lage
14,"2014-08-15 17:12:11","2014-08-15 17:12:11",deu,Category,2,url_name,lage
15,"2014-08-15 17:12:11","2014-08-15 17:12:11",eng,Category,3,name,Transport
16,"2014-08-15 17:12:11","2014-08-15 17:12:11",eng,Category,3,url_name,transport
17,"2014-08-15 17:12:11","2014-08-15 17:12:11",nld,Category,4,name,"Eten & Drinken"
18,"2014-08-15 17:12:11","2014-08-15 17:12:11",nld,Category,4,url_name,eten-drinken
Records in table categories
id,created,modified,total_services
1,"2014-08-15 17:08:26","2014-08-15 17:08:26",0
2,"2014-08-15 17:09:47","2014-08-15 17:09:47",0
3,"2014-08-15 17:12:11","2014-08-15 17:12:11",0
4,"2014-08-15 17:12:11","2014-08-15 17:12:11",0
CategoriesController.php
$query2 = array(
'recursive' => 1
);
$this->Category->bindTranslation(array(
'name' => 'name_i18n',
'url_name' => 'url_name_i18n'
));
$categories = $this->Category->find(
'all',
$query2
);
debug($categories);
Result of $categories
array(
(int) 0 => array(
'Category' => array(
'id' => '1',
'created' => '2014-08-15 17:08:26',
'modified' => '2014-08-15 17:08:26',
'total_services' => '0',
'locale' => 'eng',
'name' => 'Entertainment',
'url_name' => 'entertainment'
),
'Service' => array(),
'name_i18n' => array(
(int) 0 => array(
'id' => '1',
'created' => '2014-08-15 17:08:26',
'modified' => '2014-08-15 17:08:26',
'locale' => 'eng',
'model' => 'Category',
'foreign_key' => '1',
'field' => 'name',
'content' => 'Entertainment'
),
(int) 1 => array(
'id' => '9',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'deu',
'model' => 'Category',
'foreign_key' => '1',
'field' => 'name',
'content' => 'Unterhaltung'
),
(int) 2 => array(
'id' => '11',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'nld',
'model' => 'Category',
'foreign_key' => '1',
'field' => 'name',
'content' => 'Vermaak'
)
),
'url_name_i18n' => array(
(int) 0 => array(
'id' => '2',
'created' => '2014-08-15 17:08:26',
'modified' => '2014-08-15 17:08:26',
'locale' => 'eng',
'model' => 'Category',
'foreign_key' => '1',
'field' => 'url_name',
'content' => 'entertainment'
),
(int) 1 => array(
'id' => '10',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'deu',
'model' => 'Category',
'foreign_key' => '1',
'field' => 'url_name',
'content' => 'unterhaltung'
),
(int) 2 => array(
'id' => '12',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'nld',
'model' => 'Category',
'foreign_key' => '1',
'field' => 'url_name',
'content' => 'vermaak'
)
)
),
(int) 1 => array(
'Category' => array(
'id' => '2',
'created' => '2014-08-15 17:09:47',
'modified' => '2014-08-15 17:09:47',
'total_services' => '0',
'locale' => 'eng',
'name' => 'Location',
'url_name' => 'location'
),
'Service' => array(),
'name_i18n' => array(
(int) 0 => array(
'id' => '3',
'created' => '2014-08-15 17:09:47',
'modified' => '2014-08-15 17:09:47',
'locale' => 'eng',
'model' => 'Category',
'foreign_key' => '2',
'field' => 'name',
'content' => 'Location'
),
(int) 1 => array(
'id' => '5',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'nld',
'model' => 'Category',
'foreign_key' => '2',
'field' => 'name',
'content' => 'Locatie'
),
(int) 2 => array(
'id' => '13',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'deu',
'model' => 'Category',
'foreign_key' => '2',
'field' => 'name',
'content' => 'Lage'
)
),
'url_name_i18n' => array(
(int) 0 => array(
'id' => '4',
'created' => '2014-08-15 17:09:47',
'modified' => '2014-08-15 17:09:47',
'locale' => 'eng',
'model' => 'Category',
'foreign_key' => '2',
'field' => 'url_name',
'content' => 'location'
),
(int) 1 => array(
'id' => '6',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'nld',
'model' => 'Category',
'foreign_key' => '2',
'field' => 'url_name',
'content' => 'locatie'
),
(int) 2 => array(
'id' => '14',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'deu',
'model' => 'Category',
'foreign_key' => '2',
'field' => 'url_name',
'content' => 'lage'
)
)
),
(int) 2 => array(
'Category' => array(
'id' => '3',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'total_services' => '0',
'locale' => 'eng',
'name' => 'Transport',
'url_name' => 'transport'
),
'Service' => array(),
'name_i18n' => array(
(int) 0 => array(
'id' => '7',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'nld',
'model' => 'Category',
'foreign_key' => '3',
'field' => 'name',
'content' => 'Vervoer'
),
(int) 1 => array(
'id' => '15',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'eng',
'model' => 'Category',
'foreign_key' => '3',
'field' => 'name',
'content' => 'Transport'
)
),
'url_name_i18n' => array(
(int) 0 => array(
'id' => '8',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'nld',
'model' => 'Category',
'foreign_key' => '3',
'field' => 'url_name',
'content' => 'vervoer'
),
(int) 1 => array(
'id' => '16',
'created' => '2014-08-15 17:12:11',
'modified' => '2014-08-15 17:12:11',
'locale' => 'eng',
'model' => 'Category',
'foreign_key' => '3',
'field' => 'url_name',
'content' => 'transport'
)
)
)
)
As you can see, records with id 17 and 18 from table category_18ns and 4 from table categories are not included in the result ($categories). I want that this also are included, regardless of the current locale.
For now I have a quick and dirty solution for my case. I'm retrieving data by my own sql statement. But I now this is not a save solution. So if somebody has a better (more secure) solution, I would like to know that.
My current quick and dirty solution:
Category.php (model)
/**
* Returns all categories with all translated fields, independent of locale setting.
*/
public function getAllTranslations() {
$result = null;
$queryResults = $this->query('SELECT categories.*, category_i18ns.* FROM categories INNER JOIN category_i18ns ON category_i18ns.foreign_key = categories.id;');
foreach($queryResults as $queryResult) {
$locale = $queryResult['category_i18ns']['locale'];
$field = $queryResult['category_i18ns']['field'];
$content = $queryResult['category_i18ns']['content'];
$categoryId = $queryResult['categories']['id'];
if(!isset($result[$categoryId])) {
$result[$categoryId] = $queryResult['categories'];
$result[$categoryId][$field][$locale] = $content;
} else {
$result[$categoryId][$field][$locale] = $content;
}
}
return $result;
}

CakePhp saveAssociated deep=true not working

i am trying to save an array as the one shown below with saveAssociated and the deep options set to true, but it's not saving the Answer, only the Quiz and the Question. I'm using CakePhp 2.3.1
$myarray = array(
'Quiz' => array(
'title' => 'Test di Prova copy',
'description' => '',
'timer' => '5',
'days' => '10',
'tries' => '2',
'pass_percentage' => '90',
'active' => true
),
'Question' => array(
(int) 0 => array(
'question' => 'Quanti valori può assumere un bit?',
'score' => '10',
'position' => '0',
'created' => '0000-00-00 00:00:00',
'modified' => '2013-04-10 13:04:50',
'Answer' => array(
(int) 0 => array(
'answer' => '2',
'right' => true
),
(int) 1 => array(
'answer' => '4',
'right' => false
),
(int) 2 => array(
'answer' => '8',
'right' => false
),
(int) 3 => array(
'answer' => 'non lo sò
',
'right' => false
)
)
),
(int) 1 => array(
'question' => 'Quale tra questi tag Html identifica l'header più grande di dimensioni?',
'score' => '10',
'position' => '2',
'created' => '0000-00-00 00:00:00',
'modified' => '2013-04-10 13:04:50',
'Answer' => array(
(int) 0 => array(
'answer' => 'H6',
'right' => false
),
(int) 1 => array(
'answer' => 'H4',
'right' => false
),
(int) 2 => array(
'answer' => 'H1',
'right' => true
)
)
),
(int) 2 => array(
'question' => 'Da quanti bit è composto un byte?',
'score' => '10',
'position' => '1',
'created' => '0000-00-00 00:00:00',
'modified' => '2013-04-10 13:04:50',
'Answer' => array(
(int) 0 => array(
'answer' => '2',
'right' => false
),
(int) 1 => array(
'answer' => '4',
'right' => false
),
(int) 2 => array(
'answer' => '6',
'right' => false
),
(int) 3 => array(
'answer' => '8',
'right' => true
)
)
)
)
);
$this->Quiz->saveAssociated($myarray, array('deep'=>true));
That data structure would work with saveAll, have you tried that?
<?php
$this->Model1->saveAll($myarray, array('deep' => true));
?>
saveAll internally calls saveAssociated.
I believe that should work for you.

CakePHP: testing -> ValidationException

I'm new to programming and testing. I'm stuck at this testing, which throws an exception.
Please help me as I really don't get how I should approach this question.
My method to test:
public function saveNewInstitution($institutionData, $user) {
$institutionData[$this->alias]['isActive'] = 1;
$institutionData[$this->alias]['users_id'] = $user['User']['id'];
$this->create();
$this->set($institutionData);
if ($this->validates()) {
return $this->save();
} else {
throw new ValidationException('Not all fields are filled out correct');
}
}
My testclass:
public function testSaveNewInstitution() {
$result = array(
'Institution' => array(
'id' => 2,
'name' => 'Spitex',
'address' => 'Hauptweg 4',
'postcode' => '1234',
'city' => 'huuh',
'phone_number' => '123 456 78 90',
'email' => 'staufen#tsdy.huuh',
'comment' => '',
'isActive' => TRUE,
'users_id' => 2,
'institution_types_id' => 5
),
'Users' => array(
'id' => 2,
'email' => 'herbert#xyz.ch',
'password' => AuthComponent::password('12345678'),
'isMale' => TRUE,
'first_name' => 'Herbert',
'last_name' => 'Müller',
'address' => 'Hauptstrasse 1',
'postcode' => '1234',
'city' => 'Zürich',
'phone_number' => '123 456 78 90',
'isActive' => FALSE,
'institutions_id' => 2,
'groups_id' => 4
),
'InstitutionTypes' => array(
'id' => 5,
'name' => 'Spitex'
),
'Assignee' => array('0' => array(
'id' => 2,
'email' => 'herbert#xyz.ch',
'password' => AuthComponent::password('12345678'),
'isMale' => TRUE,
'first_name' => 'Herbert',
'last_name' => 'Müller',
'address' => 'Hauptstrasse 1',
'postcode' => '1234',
'city' => 'Zürich',
'phone_number' => '123 456 78 90',
'isActive' => FALSE,
'institutions_id' => 2,
'groups_id' => 4
))
);
$expected = $this->Institution->saveNewInstitution($result, 2);
$this->assertEqual($result, $expected);
}
public function testSaveNewInstitutionException() {
$this->setExpectedException('ValidationException');
$expected = array(
'Institution' => array(
'id' => 2,
'name' => 'Spitex',
'address' => 'Hauptweg 4',
'postcode' => '1234',
'city' => 'huuh',
'phone_number' => '123 456 78 90',
'email' => 'staufen#xyz.huuh',
'comment' => '',
'isActive' => TRUE,
'users_id' => 2,
'institution_types_id' => 5
),
'Users' => array(
'id' => 2,
'email' => 'herbert#xyz.ch',
'password' => AuthComponent::password('12345678'),
'isMale' => TRUE,
'first_name' => 'Herbert',
'last_name' => 'Müller',
'address' => 'Hauptstrasse 1',
'postcode' => '1234',
'city' => 'Zürich',
'phone_number' => '123 456 78 90',
'isActive' => FALSE,
'institutions_id' => 2,
'groups_id' => 4
),
'InstitutionTypes' => array(
'id' => 5,
'name' => 'Spitex'
),
'Assignee' => array('0' => array(
'id' => 2,
'email' => 'herbert#mueller.ch',
'password' => AuthComponent::password('12345678'),
'isMale' => TRUE,
'first_name' => 'Herbert',
'last_name' => 'Müller',
'address' => 'Hauptstrasse 1',
'postcode' => '1234',
'city' => 'Zürich',
'phone_number' => '123 456 78 90',
'isActive' => FALSE,
'institutions_id' => 2,
'groups_id' => 4
))
);
$this->Institution->saveNewInstitution($expected, 2);
}
My exception:
**VALIDATIONEXCEPTION**
Not all fields are filled out correct
Test case: InstitutionTest(testSaveNewInstitution)
Stack trace:
/app/Test/Case/Model/InstitutionTest.php : 148
InstitutionTest::testSaveNewInstitution
/usr/lib/php/PHPUnit/Framework/TestCase.php : 969
/usr/lib/php/PHPUnit/Framework/TestCase.php : 824
/usr/lib/php/PHPUnit/Framework/TestResult.php : 648
/usr/lib/php/PHPUnit/Framework/TestCase.php : 769
/lib/Cake/TestSuite/CakeTestCase.php : 78
/usr/lib/php/PHPUnit/Framework/TestSuite.php : 775
/usr/lib/php/PHPUnit/Framework/TestSuite.php : 745
/usr/lib/php/PHPUnit/TextUI/TestRunner.php : 346
/lib/Cake/TestSuite/CakeTestRunner.php : 57
/lib/Cake/TestSuite/CakeTestSuiteCommand.php : 111
/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php : 242
/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php : 99
/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php : 116
/app/webroot/test.php : 92
9/9 test methods complete: 8 passes, 0 fails, 12 assertions and 1 exceptions.
as stated in the comments, the issue is pretty straigt forward. your validation fails and therefore the exception is thrown (as desired by your code).
if you want to debug it, try to determine what
$this->validationErrors
contains after the save() (before/instead of throwing the exception). then you know why the validation fails.

Resources