Salut,
J'ai appris comment faire mes applications web en MVC avec le tutoriel ´Créer un MVC´ et je me pose une questions sur les modèles avec l'accès à la base de donnée :

J'ai par exemple 2 tables reliée entre elles.
Dans certains cas j'ai besoin d'utiliser ma première table et d'autre j'utilise la seconde. Mais il y a encore un autre cas où j'utilise les 2, donc il faudrait faire une jointure.

Comment je doivent m'y prendre pour que ça soir bien clair ?

  • Je crée un 3iem modèle juste pour la jointure ?
  • J'ajoute une nouvelle fonction à un des modèle qui va faire une jointure ?
  • Ou alors celle que j'utilise actuellement qui m'a l'air plus clair mais doit être beaucoup plus bouffante en ressource : Dans mon contrôleur, je récupère la première table (celle qui a la clé primaire) puis je fait un foreach(par référence bien sur, sinon ça n'irait pas fort) qui demande au modèle de la seconde table les informations qui vont avec chacune de la seconde table. Il me semble que cet exemple est dur à comprendre donc un code s'impose :

    Class Infos extends Model{
    var $Models = array('Model1', 'Model2');
    function index(){
    $rep = $this->Model1->getInfos();
    foreach($rep as &$r){
    $r->enfants = $this->Model2->getDescription();
    }
    $this->set('infos' => $rep);
    return $this->render('index');
    }
    }

Qu'en pensez-vous ? Quelle méthode préférez-vous ?

Ps: Je sais que j'expose toutes les solutions qui me viennent à l'esprit et qu'elle fonctionne toutes, mais je voudrais juste avoir l'avis de personnes expérimentée afin d'avoir mon application MVC la plus clair possible.

5 réponses


siriu
Réponse acceptée

J'aimerai bien voir ça également dans une vidéo, ça serait plus parlant, j'avoue avoir du mal aussi

MightyDespe
Réponse acceptée

Je bosse sur la même chose :). Moi je passe par des variables $this->BelongsTo et $this->hasMany.
Je peux te montrer le code mais j'ai l'impression d'en faire beaucoup pour peux de chose

public function find($options = '', array $data = array()) {
        $join = '';
        $count = '';
        $fields = '*';
        $whereCondition = '1=1';
        $andCondition = '1=1';
        $group = '';
        $order = '';
        $limit = '';
        if (!empty($options) && in_array($options, $this->findQueryOptions)) {
            if ($options == 'all') {
                $order = "ORDER BY ".$this->name.".id DESC";
            }
            if ($options == 'count') {
                $fields = '';
            }else {
                $fields = '*';
            }
        }
        if (isset($data)) {
            foreach ($data as $key => $value) {
                if ($key === 'fields') {
                    $fields = $value;
                }
                if ($key === 'rule' && is_array($value)&& $options == 'count') {
                    extract($value);
                    $option = isset($option) ? strtoupper($option) : "";
                    $field = isset($field) ? $field : "*";
                    $alias = isset($alias) ? $alias : "nbre";
                    $count = "COUNT($option $field) AS $alias";
                }
                if (($key === 'where' || $key === 'and') && is_array($value)) {
                    extract($value);
                    $operator = isset($operator) ? $operator : "=";
                    if (is_string($value)) {
                        $value = "'" . $value . "'";
                    }
                    if ($key === 'where'){
                        $whereCondition = "$field$operator$value";
                    } else {
                        $andCondition = "$field$operator$value";
                    }
                }
                if ($key === 'group') {
                    $group = "GROUP BY $value";
                }
                if ($key === 'order' && is_array($value)) {
                    extract($value);
                    $field = isset($field) ? $field : "$this->name.id";
                    $type = isset($type) ? strtoupper($type) : "DESC";
                    $order = "ORDER BY $field $type";
                }
                if ($key === 'limit' && is_array($value)) {
                    extract($value);
                    $start = isset($start) ? $start : 0;
                    $offset = isset($offset) ? $offset : 1;
                    $limit = "LIMIT $start,$offset";
                }
            }
        }
        if (isset($this->belongsTo) && isset($this->hasMany)){
            $singularizedBelongsTo =singularize($this->belongsTo);
            $singularizedName =singularize($this->name);
            $join = "LEFT JOIN $this->belongsTo ON $this->name.".$singularizedBelongsTo."_id=$this->belongsTo.id";
            $join .= " LEFT JOIN $this->hasMany ON $this->name.id=$this->hasMany.".$singularizedName."_id";
        } else {
            if (isset($this->belongsTo)) {
                $singularized = singularize($this->belongsTo);
                $join = "LEFT JOIN $this->belongsTo ON $this->name.".$singularized."_id=$this->belongsTo.id";
            }
            if (isset($this->hasMany)){
                $singularized = singularize($this->name);
                $join = "LEFT JOIN $this->hasMany ON $this->name.id=$this->hasMany.".$singularized."_id";
            }
        }
        $sql = "SELECT $fields $count FROM $this->name $join WHERE $whereCondition AND $andCondition $group $order $limit";
        return $this->execute($sql, true);
    }

Mon code me semble un peu barbare tout de même :/

fenchi
Auteur
Réponse acceptée

Pas mal ton code MightyDespe, j'aime, j'aime. Tu peux m'expliquer $this->BelongsTo et $this->hasMany ?

Tu devrais utiliser Cakephp, si tu as compris le principe du MVC ça va te plaire ! ;) Sinon pour ton problème je pense qu'il faudrait créer une méthode qui vérifie si ta variable $Models est un tableau et qu'elle fasse les jointures

Désolé pour le retard de réponse mais j'étais parti quelque part en méditerranée.... **@DevAddict** : - Pas mal l'idée de tableau avec les jointures par contre je pense que faire des requêtes comme celle-ci ça doit bouffer des ressources côté GBD ! **@fenchi :** - pour hasMany (a plusieurs) si tu as plusieurs commentaires sur un post ca te permet de faire un lien entre la base de données posts et la base de données comments en gros $this->hasMany = 'comments' - pour belongsTo (appartient à) si tu as besoin de lié un commentaire à un post par exemple ou une catégorie à un post et ici la variable $this->belongsTo = 'posts'