[CakePHP] Les relations pour mes modèles

samsurr
Invité n'ayant pas de compte PHPfrance

05 avr. 2011, 23:30

Bonjour,

Je viens vers vous car je viens de terminer la mise en place de mes relations au sein de ma base de données et cela fonctionne comme je le souhaites au niveau des mise à jour/suppression de données, voici comment se présente (brièvement) mes tables :



Admins :

id (PK)

Users :

id (PK)

Assistances :

id (PK)
user_id (FK)

Conversations :

id (PK, UUID)
admins_id (FK)
users_id (FK)
assistances_id (FK)


Mon plus gros soucis actuellement, c'est tout simplement que je n'arrive pas à saisir la relation hasMany et/ou belongsTo dans mon exemple concret, de plus ma table assistances étant mère et fille à la fois me pose encore plus de soucis dans la déclaration de la relation dans mon modèle. Auriez vous une piste et/ou une meilleure façon de m'expliquer les relations que je cites.

Cordialement, sam !

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

06 avr. 2011, 07:40

Modération :
Afin d'obtenir plus de réponses, le sujet a été déplacé dans un forum plus approprié.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 398 Messages

06 avr. 2011, 10:13

Avec ta structure de table, je ne vois pas trop, mais prenons un exemple.
Nous avons deux tables principales lié à une table de type id/libelle :
create table blabla(
    id_blabla SERIAL NOT NULL,
    lib_blabla varchar(20),
 CONSTRAINT pk_1 PRIMARY KEY (id_blabla )
)

create table_t1(
   id_1 SERIAL NOT NULL,
   id_bla integer,
   lib_1 varchar(20)

 CONSTRAINT pk_1 PRIMARY KEY (id_1 ),
CONSTRAINT fk_1 FOREIGN KEY (id_bla) REFERENCES blabla(id_blabla )
)

create table_t2(
   id_2 SERIAL NOT NULL,
   id_bla2 integer,
   lib_2 varchar(20)

 CONSTRAINT pk_1 PRIMARY KEY (id_2 ),
CONSTRAINT fk_1 FOREIGN KEY (id_bla2 ) REFERENCES blabla(id_blabla )
)
Nos deux tables principales référencent par clés étrangères la table blabla.

Dans les model de table_t1 et table_t2, on définira le tableau $belongsTo, afin de lier la table blabla
var $belongsTo = array(
			'Blabla' =>
					array('className' => 'Blabla',
						'foreignKey' => 'id_bla',
						'conditions' => '',
						'fields' => '',
						'order' => '',
						'counterCache' => ''
						)
);
Tandis que sur le model de Blabla, on souhaite récupérer les Models lié à notre table. Vu que la clé étrangère ne se trouve pas sur cette table, on ne peut appliquer de $belongsTo, on applique le $hasMany()
var $hasMany = array(
			'TableT1' =>
				array('className' => 'TableT1',
						'foreignKey' => 'id_blabla',
						'conditions' => '',
						'fields' => '',
						'order' => '',
						'limit' => '',
						'offset' => '',
						'dependent' => '',
						'exclusive' => '',
						'finderQuery' => '',
						'counterQuery' => ''
				),
			'TableT2' =>
				array('className' => 'TableT2',
						'foreignKey' => 'id_blabla',
						'conditions' => '',
						'fields' => '',
						'order' => '',
						'limit' => '',
						'offset' => '',
						'dependent' => '',
						'exclusive' => '',
						'finderQuery' => '',
						'counterQuery' => ''
				),

	);

Tu as le cookBook pour t'aider : http://book.cakephp.org/#!/view/1039/As ... s-Together
Les relations sont expliqués :)
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe

samsurr
Invité n'ayant pas de compte PHPfrance

06 avr. 2011, 23:37

Merci Balistik pour tes infos, je penses être au final parvenu à avoir ce que je voulais, mais je suis de nouveau confronté à un problème, je me trouve dans l'impossibilité de valider mon formulaire avec le array $validate que j'ai intégré dans mon modèle, de plus je suis obligé de nommer mon champ "Assistance" au pluriel dans mon formulaire, est-ce un soucis de convention cake ou assistance n'est pas reconnu ?

Pour ma première question voici mes modèles, controlleurs et ma vue :
<?php

class ConversationsController extends AppController
{

    var $name = 'Conversation';
    var $uses = array('Conversation', 'Assistance');
    
    function add()
    {
        if(isset($this->data))
        {
        $this->Conversation->set($this->data);
                if($this->Conversation->validates())
                {
                        $this->data = Sanitize::clean($this->data);
                        if($this->Conversation->saveAll($this->data))                                        // Inscription bdd réussie
                        {
                            debug($this->data);
                        } else {
                            $this->Session->setFlash("Une erreur s'est produite lors de l'ajout dans la base de données.");
                        }
                } else {
                        $this->Session->setFlash("Veuillez corriger les erreurs du formulaire.");
                        $this->validateErrors($this->Conversation);                                       // Erreur dans le formulaire, réaffichage
                }
        }
        $this->set('errors', $this->Conversation->validationErrors);
    }
}

<?php
class Assistance extends AppModel {

	var $name = 'Assistance';

	var $belongsTo = array(
		'Users' => array(
			'className' => 'Users',
			'foreignKey' => 'user_id',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		)
        );
        var $hasMany = array(
                'Conversations' => array(
			'className' => 'Conversations',
			'foreignKey' => 'assistances_id',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		)
	);

        var $_schema = array(
                "about" => array(
                    "type" => "string",
                    "length" => 255
                ),
                "knowledge" => array(
                    "type" => "select"
                ),
                "priority" => array(
                    "type" => "select"
                ),
                "message" => array(
                    "type" => "string",
                    "length" => 4000
                )
        );

        var $validate = array(
                "about" => array(
                    "notEmpty" => array(
                        "rule" => "notEmpty",
                        "message" => "Vous devez entrer un sujet pour votre demande."
                    ),
                    "between" => array(
                        "rule" => array('between', 10, 255),
                        "message" => "Le sujet de votre demande doit contenir au minimum 10 caractères."
                    )
                ),
                "message" => array(
                    "notEmpty" => array(
                        "rule" => "notEmpty",
                        "message" => "Le champ message ne doit pas rester vide."
                    ),
                    "between" => array(
                        "rule" => array('between', 50, 4000),
                        "message" => "Votre message doit contenir 50 caractères minimum."
                    )
                )
        );

}
<?php
    // Connecté, affichage du formulaire
    echo "<h3>Formulaire de demande d'assistance</h3>";
    echo $this->element('errors', array('errors' => $errors));
    echo $this->Form->create('Conversations', array('action' => 'add'));
    echo $this->Form->hidden('Assistances.users_id', array('value' => $session->read('Auth.User.id')));
    echo $this->Form->hidden('Conversation.users_id', array('value' => $session->read('Auth.User.id')));
    echo $this->Form->input('Assistances.about', array('label' => 'Sujet de la demande', 'error' => false));
    echo $html->tag('label', 'Vos connaissances', array('for' => 'UserKnowledge'));
    $options_list_connaissances = array('nulles' => 'Nulles', 'faibles' => 'Faibles', 'moyennes' => 'Moyennes', 'bonnes' => 'Bonnes', 'conséquentes' => 'Conséquentes');
    echo $this->Form->select('Assistances.knowledge', $options_list_connaissances, "moyennes", array("empty" => false));
    echo $html->tag('br');
    echo $html->tag('label', 'Priorité de la demande', array('for' => 'UserPriority'));
    $options_list_priorite = array('sansimportance' => 'Sans importance', 'faible' => 'Faible', 'moyenne' => 'Moyenne', 'urgente' => 'Urgente');
    echo $this->Form->select('Assistances.priority', $options_list_priorite, "sansimportance", array("empty" => false));
    echo $html->tag('br');
    echo $html->tag('label', 'Votre demande', array('for' => 'UserMessage'));
    echo $html->tag('br');
    echo $this->Form->textarea('Assistances.message', array("rows" => 8, "cols" => 60));
    echo $this->Form->end('Envoyer ma demande');
?>

Eléphant du PHP | 398 Messages

07 avr. 2011, 19:25

dans la vue, le nom du champ s'écrit de la forme :
$html->input('Model\nom_champ', array());
et non pas
$html->input('Model.nom_champ', array());
Par contre, ce qui m'étonne, ce sont tes textareas. De tête, il me semble que c est $html->textarea() ou $form->textarea()
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe

samsurr
Invité n'ayant pas de compte PHPfrance

07 avr. 2011, 22:40

Bonsoir Balistik,

Es-tu sur pour l'histoire du backslash pour séparer modèle et champ, car avec le point ça fonctionne, mais la pas du tout, il interprète mon nom de champ tel qu'il est.

Eléphant du PHP | 398 Messages

08 avr. 2011, 10:44

ça doit dépendre de la version de cakePHP alors :/.J'utilise 1.1 ou 1.2.
Mais je me suis trompé sur un truc, c est pas 'Model\nom_champ', mais 'Model/nom_champ'
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe

samsurr
Invité n'ayant pas de compte PHPfrance

08 avr. 2011, 11:05

Bonjour,

A mon avis les conventions ont changées, je suis en 1.3 et je suis presque sur que c'est le "point" . qui sépare le modèle et le nom du champ. Par contre j'ai remarqué une choses, c'est que si je définis ma règle dans mon modèle "Conversation" et que je renomme mes champs en "Conversation.xxxx" il va bien chercher le tableau de validation dans le modèle mais pas quand il s'agit de "Assistance", reste à savoir pourquoi aussi.