Bonjour
J'ai un soucis de compréhension avec une base de données ayant 3 tables de jonction,
Voilà mon MCD :
En effet avec la console de cakePHP (2.5.2) il m'est proposé de donner un nom de clef primaire quand je veux crée le model actors_videos de ma table de jonction, hors, comme vous le savez ce genre de table n'a pas à en avoir ! Du coup je ne comprends pas...
Merci,
Bonsoir,
si je me souviens bien, cakePhp met des clés primaires sur la table permettant les liaisons HABTM. (n<-> n)
La structure est alors la suivante:
id id_model1 id_model2
cordialement
Salut, antho ;)
Alors j'ai bien progresser depuis le début de mon post ! d'ailleurs j'ai éditer mon MCD.
Tout est bien fonctionnel, cependant j'ai un soucis au niveau de la récupération de mes lignes 'name' :
comme suis :
1)J'affiche la liste des videos enregistrées (liée à la table Actors, par une table de jonction: voir MCD 'videos_actors')
2)Puis je sélectionne une vidéos via l'action admin view,
les acteurs liées à la vidéo sélectionnée s'affichent, mais le champs 'nationality' de l'acteur affiche l'id et non le 'name' comme je le souhaiterais.
Je précise que ma table Actors est lié à ma table Nationality via une clef étrangère classique et que ma table Actors est lié à ma table Videos par une table de jonction => videos_actors.
Pourtant dans mon code j'ai bien précisé les bonnes associations (belongsTo, HasMany etc)
Dans mes models :
Videos
Actors
etc
L'id que tu cites doit être le nationality_id qui lui est bien dans ta table actors.
Si ton modèle est bien lié, pour récupérer le name il faut aller le chercher dans le modèle lié.
Schématiquement tu dois avoir un truc du style:
(
0 => ('Actor' = > ( 'id' => 'truc',
name=>'truc',
......
'Nationality' => array(
'id' => 'truc' ,
....
)
)
)
Il me semble que j'ai tout bon :
Model Videos :
/**
* belongsTo associations
*
* @var array
*/
public $belongsTo = array(
'Type' => array(
'className' => 'Type',
'foreignKey' => 'type_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Nationality' => array(
'className' => 'Nationality',
'foreignKey' => 'nationality_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Genre' => array(
'className' => 'Genre',
'foreignKey' => 'genre_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Support' => array(
'className' => 'Support',
'foreignKey' => 'support_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
/**
* hasMany associations
*
* @var array
*/
public $hasMany = array(
'Media' => array(
'className' => 'Media',
'foreignKey' => 'video_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
/**
* hasAndBelongsToMany associations
*
* @var array
*/
public $hasAndBelongsToMany = array(
'Actor' => array(
'className' => 'Actor',
'joinTable' => 'videos_actors',
'foreignKey' => 'video_id',
'associationForeignKey' => 'actor_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
),
'Director' => array(
'className' => 'Director',
'joinTable' => 'videos_directors',
'foreignKey' => 'video_id',
'associationForeignKey' => 'director_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
),
'Producer' => array(
'className' => 'Producer',
'joinTable' => 'videos_producers',
'foreignKey' => 'video_id',
'associationForeignKey' => 'producer_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
)
);
}
Model Actors :
/**
* belongsTo associations
*
* @var array
*/
public $belongsTo = array(
'Nationality' => array(
'className' => 'Nationality',
'foreignKey' => 'nationality_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
/**
* hasAndBelongsToMany associations
*
* @var array
*/
public $hasAndBelongsToMany = array(
'Video' => array(
'className' => 'Video',
'joinTable' => 'videos_actors',
'foreignKey' => 'actor_id',
'associationForeignKey' => 'video_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
)
);
}
Model Nationality :
/**
* hasMany associations
*
* @var array
*/
public $hasMany = array(
'Actor' => array(
'className' => 'Actor',
'foreignKey' => 'nationality_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
'Video' => array(
'className' => 'Video',
'foreignKey' => 'nationality_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
En somme si je fais :
'fields' => array('Nationality_id'=> 'Nationalities.name'),
Mais cela ne fonctionne pas
Fait ta requete et debug le résultat. Je pense qu'il va falloir le remonter à la main après la requete si tu veux absolument qu'il soit au meme niveau dans l'array que tu envoies à la vue
en fait, ma question serais déjà plus,
Est ce qu'il faut créer les modèles ainsi que les contrôleurs affiliés pour mes tables de jonction et donc, leur mettre des clés primaires unique en PLUS des clés primaires de mes tables à joindre ?
Parceque dans cakepHP je dois donner une clé primaire à mes tables de jonction...
ma fonction admin_view:
public function admin_view($id = null) {
if (!$this->Actor->exists($id)) {
throw new NotFoundException(__('Invalid actor'));
}
$options = array('conditions' => array('Actor.' . $this->Actor->primaryKey => $id));
$this->set('actor', $this->Actor->find('first', $options));
}
Salut,
Tu devrais appliquer ce que t'as dit antho dans son 1er post, c'est la convention de CakePHP. Il faut mettre une clé primaire qui s'auto incrémente dans tes tables de jonctions si tu n'appliques pas ça, tu devras faire des requêtes SQL perso. Ce serait dommage de faire un travail déjà prévu dans CakePHP, d'autant que pas mal de choses sont automatisées avec le HABTM.
Voir Les conventions de CakePHP
La phrase qui va bien dans le chapitre "Model and Database conventions" : CakePHP does not support composite primary keys. If you want to directly manipulate your join table data, use direct query calls or add a primary key to act on it as a normal model. For example:
CREATE TABLE posts_tags ( id INT(10) NOT NULL AUTO_INCREMENT, post_id INT(10) NOT NULL, tag_id INT(10) NOT NULL, PRIMARY KEY(id));
Par contre, il faudrait que tu sois plus explicite dans tes questions, personnellement j'ai du mal à comprendre ce que tu souhaites faire et ce qui ne fonctionne pas dans ton dernier post.
Est ce que dans qu'il faut créer les modèles et donc, les contrôleurs pour mes tables de jonction et donc, leur mettre des clé primaire unique en PLUS des clé primaire de mes tables à joindre ?
Par ce que je dois donnée une clé primaire à mes tables de jonctions...
salut,
En effet je viens de me relire et cela étant très décousu et criblé de fautes...
J'ai édité !
La réponse d'antho07 m'avait échappée --> id, id_model1, id_model2
Cela répond à ma question, il me faut bien une clé primaire pour chacune de mes tables de jonction.
Mais, dois je créer le modèle et le contrôleur de toutes mes tables de jonction ?
Est ce bon cette fois ?
Merci à vous 2, vraiment sympa de votre part ! !
PS :
antho07, tu vas me ruiner en bières...