Bonjour,
Je suis sous CakePhp 2.x
Et Je découvre que sur une fonction de simple affichage (ici l'affichage d'un article), des requêtes update de champs "count" sont faites à chaque rechargement de la page.

Alors que j'attends plutôt ce comportement qui est normal lors d'un ajout, par exemple si j'ajoute un article, je comprend bien que le champ post_count de la catégorie de l'article s'incrémente de +1 (il y a un article en plus dans cette catégorie)

Ce que je fais

Dans mon model Post je crée une relation belongsTo sur le modèle Category en lui passant un counterCache

  // model Post
  public $belongsTo = array(
        'Category' => array(
            'counterCache' => array('post_count' => array('Post.online' => 1))
        ),

Ce que je veux

Je cherche simplement à obtenir un update du champs post_count de la table categories uniquement lorsque j'ajoute un post

Ce que j'obtiens

Or j'obtiens un update lorsque je fais un simple find first pour afficher l'article :(

// Post Controller
$post = $this->Post->find('first',array(
            'conditions' => array('Post.id' => $id),
            'recursive'  => -1,
            'contain' => array('Media', 'Category', 'User')
        ));

1 - Quelqu'un est déjà tombé sur ce comportement étrange sous CakePhp 2.XX ?
2 - Est-ce que ce problème peut venir de MySql ?

4 réponses


Lartak
Réponse acceptée

Bonsoir.

Peut-on utiliser une autre méthode que le saveField pour sauvegarder un simple champ ?

Tu as aussi la méthode set pour mettre à jour un champ, voir : Model::set($one, $two = null).

FactureHero.com
Auteur
Réponse acceptée

Je reviens vers toi Lartak car j'ai essayé en utilisant SET. Mon résultat me dit que ce n'est pas ici que ça se joue, mais au niveau de la ligne suivante (SET ne faisant que préparer la requête). Les 3 méthodes que j'ai essayées :

//méthode 1
  $this->Post->id = $id;
  $this->Post->saveField('viewcount', $d['post']['Post']['viewcount']+1);
  // résultat : 14 requêtes dont des SELECT redondants 
 // et des requêtes UPDATE non souhaitées sur tous les champs count des autres modèles liés en belongsTO 
// ("post_count" sur le model User, "Post_count" sur le modèle Category, 2 modèles liés au modèle Post) | ~20ms

//méthode 2
  $this->Post->id = $id;
  $this->Post->set('viewcount', $d['post']['Post']['viewcount']+1);
  $this->Post->save();
  //résultat : Idem que pour la méthode 1 et save ou saveField ne change rien | ~20ms

//méthode 3 (un updateAll avec une condition sur l'id du post)
  $this->Post->updateAll(
            array('viewcount' => $d['post']['Post']['viewcount']+1),  
            array('Post.id'=> $d['post']['Post']['id'])
);
 //résultat : 6 requêtes au lieu de 14 | ~7ms

VOILA pour le feedback. Contre toute attente c'est le UpdateAll qui est le plus précis car les autres méthodes font les liaison avec les autres modèles liées en belongsTo et font des update non sollicités sur les champs "count". (idiot quand on ne veut sauvegarder qu'un seul champ sur la table Post).

Du coup je me demande s'il est possible lors d'un save ou d'un saveField de retirer les relations belongsTo. Je n'arrive pas à trouver le truc. Mais si je le trouve, là je serai au point sur les justes requêtes :)

Whao je viens de trouver le coupable qui me fait entre autre passer de 4 à 14 requêtes...
Juste la sauvegarde d'un champs pour compter les vues au chargement de la page via la requête suivante (avec un saveField)

$this->Post->id = $id;
$this->Post->saveField('viewcount', $d['Post']['viewcount']+1);

Ces 2 lignes font exploser le nombre de requêtes select et au passage font aussi des update là où on ne demande rien (sur les autres count) Peut-on utiliser une autre méthode que le saveField pour sauvegarder un simple champ ?

Merci @Lartak Je vais tester pour voir si ça change qqchose au niveau du nombre de requêtes.