IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèques et frameworks PHP Discussion :

[CakePHP] Liaison hasMany sur une colonne personalisée


Sujet :

Bibliothèques et frameworks PHP

  1. #1
    Rédacteur
    Avatar de RideKick
    Homme Profil pro
    Directeur technique
    Inscrit en
    Septembre 2006
    Messages
    5 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2006
    Messages : 5 914
    Par défaut [CakePHP] Liaison hasMany sur une colonne personalisée
    Salut a tous,

    Je débute un peu sur le Framework Cake et je sèche un peu.

    J'ai 2 tables (et leurs models) :

    titres :
    - id (PK autoincrement)
    - ref (string)
    - libelle (string)

    stats_lectures :
    - id (PK autoincrement)
    - titre_ref (string)
    - ecoute (int)


    Je veux faire une liaison titres hasMany stats_lectures
    donc dans le model titre je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	var $hasMany = array('StatsLecture' => Array(
    	'className'=>'StatsLecture',
    	'foreignKey'=>'titre_ref',
    	'associationForeignKey'=>'ref')
    	);
    au lieu de me faire l'association :

    titres.ref <-> stats_lectures.titre_ref
    il me fait

    titres.id <-> stats_lectures.titre_ref
    J'aimerais savoir pourquoi je 'arrive pas a customiser ça ? existe-t-il une solution ou pas ?

    merci
    Pas de questions techniques en MP please

    Mon site perso

    Mon profil Viadeo

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 58
    Par défaut
    Bonjour,

    L'attribut associationForeignKey n'est valable que dans une relation HABTM pour indiquer la cle de la table de relation qui pointe vers l'id du modele lie (je ne sais pas si c'est tres clair !! ).

    Dans ce cas precis c'est a mon avis ta modelisation SQL aui est bancale car le lien entre deux modeles doit se faire principalement avec des cles primaires.
    As-tu une raison precise de ne pas avoir "titre_id" dans ta table "stats_lectures" ?

    Si ref est ta cle primaire alors marque la comme telle et cela devrait fonctionner dans tes modeles.
    Autrement tu as la solution extreme qui est d'utiliser l'attribut "finderQuery" de ta relation ... mais je te conseille plutot de repenser ta modelisation !

    Bonne journee,
    Pierre

  3. #3
    Rédacteur
    Avatar de RideKick
    Homme Profil pro
    Directeur technique
    Inscrit en
    Septembre 2006
    Messages
    5 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2006
    Messages : 5 914
    Par défaut
    Salut ,
    merci pour ta réponse c'est exactement ce que je me suis dis (pour le associationForeignKey c'est effectivement les liaisons HABTM...), du coup j'ai supprimé id dans titre et j'ai mis ref en clef primaire et ça fonctionne.

    Le truc que je trouve extrêmement dommage c'est que cette relation sert uniquement en lecture, et de surcroit cake fait 2 requête :

    - Il lit les titre et ensuite il va lire les stats en fonctions de la ref , je pensais qu'il ferait une seule requête pour récupérer le tout (a moins qu'il y ai une astuce ? )

    Secondo comme je l'ai dis, la relation est la pour la lecture, si dans mon modèle Titre, je récupère un titre et je veux créer des stats qui lui appartiennent je dois quand même renseigner l'id du titre dans la stat que je crée ....j'aurais espère que la fameuse liaison me dédouane de ça, le must serait qu'il renseigne automatiquement l'id du titre lors de la création.

    Du même coups, je me dis que supprimer la liaison a un avantage : je ne suis pas obligé de charger titre + stats a chaque lecture d'un titre .....faudrait peut être leur en parler ?

    En tout cas merci pour l'aide apportée.
    Pas de questions techniques en MP please

    Mon site perso

    Mon profil Viadeo

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 58
    Par défaut
    Bonjour,

    Citation Envoyé par RideKick Voir le message
    Le truc que je trouve extrêmement dommage c'est que cette relation sert uniquement en lecture, et de surcroit cake fait 2 requête :

    - Il lit les titre et ensuite il va lire les stats en fonctions de la ref , je pensais qu'il ferait une seule requête pour récupérer le tout (a moins qu'il y ai une astuce ? )
    Je n'ai pas trop pour habitude de regarder les requêtes qui sont effectuées sur de petites pages (car entre nous une ou deux requêtes c'est vraiment rien ), mais en règle générale tout dépend du code que tu utilise et tu peux optimiser tes requêtes en utilisant le Containable behavior.
    Dans le cas des multiples requêtes hasMany, l'astuce pour optimiser ceci consiste à momentanément remplacer cette relation par une relation "hasOne".
    Tout ceci est détaillé dans le très bon article suivant : http://www.formation-cakephp.com/53/...es-sql-cakephp

    Secondo comme je l'ai dis, la relation est la pour la lecture, si dans mon modèle Titre, je récupère un titre et je veux créer des stats qui lui appartiennent je dois quand même renseigner l'id du titre dans la stat que je crée ....j'aurais espère que la fameuse liaison me dédouane de ça, le must serait qu'il renseigne automatiquement l'id du titre lors de la création.
    Normalement CakePHP te permet d'utiliser la relation pour faire ce que tu souhaites, mais là il faudrait voir ton code pour comprendre ce que tu fais mal au niveau du formulaire ou contrôleur.

    Le code ci-dessous sauvegardera la stat liée au titre d'id "$id" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $this->Titre->id = $id;
    $this->Titre->Stat->saveAll($this->data);
    Bonne continuation dans ton apprentissage en tout cas ... si jamais tu as des questions ou autre n'hésites pas à passer sur IRC ou sur le forum cakephp-fr (j'essaie de passer régulièrement sur developpez.com mais pas aussi souvent que là-bas ... il serait bien d'avoir une salle CakePHP ici pour s'y retrouver facilement !)

    Pierre

  5. #5
    Rédacteur
    Avatar de RideKick
    Homme Profil pro
    Directeur technique
    Inscrit en
    Septembre 2006
    Messages
    5 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2006
    Messages : 5 914
    Par défaut
    Citation Envoyé par real34 Voir le message
    Bonjour,


    Je n'ai pas trop pour habitude de regarder les requêtes qui sont effectuées sur de petites pages (car entre nous une ou deux requêtes c'est vraiment rien ), mais en règle générale tout dépend du code que tu utilise et tu peux optimiser tes requêtes en utilisant le Containable behavior.
    Dans le cas des multiples requêtes hasMany, l'astuce pour optimiser ceci consiste à momentanément remplacer cette relation par une relation "hasOne".
    Tout ceci est détaillé dans le très bon article suivant : http://www.formation-cakephp.com/53/...es-sql-cakephp
    Je le vois parce que je suis en debug = 2 donc je verifie aussi les requetes, je vais essayer ton article pour voir ce que cela donne. Merci


    Citation Envoyé par real34 Voir le message
    Normalement CakePHP te permet d'utiliser la relation pour faire ce que tu souhaites, mais là il faudrait voir ton code pour comprendre ce que tu fais mal au niveau du formulaire ou contrôleur.

    Le code ci-dessous sauvegardera la stat liée au titre d'id "$id" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $this->Titre->id = $id;
    $this->Titre->Stat->saveAll($this->data);
    Moi je fais un truc du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $titre = $this->Titre->find('first', $conditions);
    $titre['Stat']['propriété'] = valeur;
    $this->Titre->Stat->save();
    J'ai aussi fais une variante avec Stat->creat() de prime abbord mais le resultat est le meme.

    Citation Envoyé par real34 Voir le message
    Bonne continuation dans ton apprentissage en tout cas ... si jamais tu as des questions ou autre n'hésites pas à passer sur IRC ou sur le forum cakephp-fr (j'essaie de passer régulièrement sur developpez.com mais pas aussi souvent que là-bas ... il serait bien d'avoir une salle CakePHP ici pour s'y retrouver facilement !)

    Pierre
    Merci a toi , le forum CakePHP ici est en cours de construction (j'en ai fais la demande hier)
    Pas de questions techniques en MP please

    Mon site perso

    Mon profil Viadeo

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 58
    Par défaut
    Bonjour RideKick,

    Serait-il possible de savoir ce que tu essaye de faire avec ce code, car pour être honnête c'est assez bizarre et je pense que tu as d'autres moyens de le faire (peut-être en réorganisant un peu ton architecture).

    Si tu veux juste changer un champ tu peux utiliser la méthode saveField() de ton modèle (cf : http://book.cakephp.org/fr/view/75/Saving-Your-Data)

    Ce n'est pas bien grave, mais si tu débutes autant commencer par prendre des bonnes habitudes de travail avec Cake ... car c'est de cette manière que tu parviendras à faire des choses géniales en très peu de lignes de code !
    En tout cas, j'ai hâte de voir cette salle ouverte sur Developpez.com et si il y a besoin d'aide il ne faut pas hésiter à me faire signe (et aux autres de la communauté francophone du framework) afin d'unir nos forces et d'éviter de s'éparpiller dans tous les sens !

  7. #7
    Rédacteur
    Avatar de RideKick
    Homme Profil pro
    Directeur technique
    Inscrit en
    Septembre 2006
    Messages
    5 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2006
    Messages : 5 914
    Par défaut
    Merci pour ta réponse.

    Pour moi l'idée est simple :

    - Je cherche un titre
    - Je lui ajoute une stat

    Maintenant j'ai modifié mes modèles comme suit :

    titres :
    - id (PK autoincrement)
    - libelle (string)

    stats_lectures :
    - id (PK autoincrement)
    - titre_id (string)
    - ecoute (int)
    Les modèles sont beaucoup plus propres diront nous.

    Maintenant comment faire simplement ? J'ai beaucoup de mal a partir du titre que j'ai récupère pour lui assigner une stat (sans compter la syntaxe mixte tableau/objet qui devra bientôt disparaitre a mon plus grand bonheur)

    Dans ma tête ça devrait tourner autour de ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $titre = $this->Titre->find('first', $conditions);
    $titre->Stat->create(); // titre_id est renseigné automatiquement
    $titre->Stat->Propriété = valeur;
    $titre->Stat->save();
    Bon en l'état la syntaxe est pas possible mais c'est l'idée.
    Pas de questions techniques en MP please

    Mon site perso

    Mon profil Viadeo

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 58
    Par défaut
    Tu pourrais avoir un truc comme ca (je pense que cela fonctionne mais j'ai pas teste ce code) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    <?php 
    public function addStat($titreId = null, $val = null) {
    	if (empty($titreId) || empty($val)) {
    		$this->redirect(xxxxx);
    	}
     
    	if ($this->Titre->read(null, $titreId)) {
    		if ($this->Titre->Stat->saveField('fieldName' => $val)) {
    			// OK
    		}
    	} else {
    		// Titre inexistant
    	}
    }
    ?>
    La cela te cree une stat ayant pour valeur de fieldname ce que tu as passe a ton action (second parametre)

  9. #9
    Rédacteur
    Avatar de RideKick
    Homme Profil pro
    Directeur technique
    Inscrit en
    Septembre 2006
    Messages
    5 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2006
    Messages : 5 914
    Par défaut
    Et bien a mon grand désespoir ça ne marche pas , le titre_id dans Stat ne se renseigne pas.
    Pas de questions techniques en MP please

    Mon site perso

    Mon profil Viadeo

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 58
    Par défaut
    Citation Envoyé par RideKick Voir le message
    Et bien a mon grand désespoir ça ne marche pas , le titre_id dans Stat ne se renseigne pas.
    Arf ... alors peut-etre en utilisant un simple save en effet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <?php 
    public function addStat($titreId = null, $val = null) {
    	if (empty($titreId) || empty($val)) {
    		$this->redirect(xxxxx);
    	}
     
    	if ($this->Titre->read(null, $titreId)) {
    		$data = array('Stat' => array('fieldName' => $val));
    		if ($this->Titre->Stat->save($data)) {
    			// OK
    		}
    	} else {
    		// Titre inexistant
    	}
    }
    ?>
    ... mais bon, la on chipote quand meme pas mal hein

  11. #11
    Rédacteur
    Avatar de RideKick
    Homme Profil pro
    Directeur technique
    Inscrit en
    Septembre 2006
    Messages
    5 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2006
    Messages : 5 914
    Par défaut
    La il ne sauvegarde pas du tout ....

    Tu vois finalement ce n'est pas une question bête
    Je continue sur ma méthode 'brutale' c'est la seule qui fonctionne.
    Pas de questions techniques en MP please

    Mon site perso

    Mon profil Viadeo

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 58
    Par défaut
    C'est juste un peu de tatonnage a faire ... mais la j'ai pas de quoi faire le test en direct
    Fais comme tu le sens de toute facon c'est vraiment anecdotique tant que cela fonctionne !

    [EDIT]
    Je suis tetu et ait vu une erreur de frappe dans mon code lors de l'appel a saveField().

    Pourrais-tu essayer ceci stp ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    <?php 
    public function addStat($titreId = null, $val = null) {
    	if (empty($titreId) || empty($val)) {
    		$this->redirect(xxxxx);
    	}
     
    	if ($this->Titre->read(null, $titreId)) {
    		if ($this->Titre->Stat->saveField('fieldName', $val)) {
    			// OK
    		}
    	} else {
    		// Titre inexistant
    	}
    }
    ?>

  13. #13
    Rédacteur
    Avatar de RideKick
    Homme Profil pro
    Directeur technique
    Inscrit en
    Septembre 2006
    Messages
    5 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2006
    Messages : 5 914
    Par défaut
    Citation Envoyé par real34 Voir le message
    Je suis tetu et ait vu une erreur de frappe dans mon code lors de l'appel a saveField().

    Pourrais-tu essayer ceci stp ?
    Tu te doute bien que j'avais repere l'erreur du (=>) quand meme ?
    donc pas mieux
    Pas de questions techniques en MP please

    Mon site perso

    Mon profil Viadeo

Discussions similaires

  1. [SYBASE ASE] Rajouter une contrainte null sur une colonne
    Par Little_Goldo dans le forum Sybase
    Réponses: 1
    Dernier message: 09/02/2005, 10h48
  2. Comment trier une DBGRID en cliquant sur une colonne
    Par sessime dans le forum Bases de données
    Réponses: 8
    Dernier message: 09/10/2004, 16h18
  3. Contraite NULL sur une colonne en fonction d'une autre colon
    Par speedy1496 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 25/04/2004, 19h29
  4. Trigger sur une colonne ?
    Par hpalpha dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 22/03/2004, 14h16
  5. Check sur une colonne de table "en cours"
    Par in dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 02/07/2003, 09h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo