2010-10-11 15 views
1

Dans mon application, j'ai un système de commentaires enfilé que j'appelle les messages d'état. J'ai quelques modèles comme suitCakePHP: Effectuer une recherche complexe

utilisateurs (id, nom ......)

status_messages (id, message, ......, user_id)

status_replies (id, message, ......, status_message_id, user_id)

est-ce la bonne façon d'écrire un système de commentaires?

Un utilisateur peut définir des messages d'état et ses amis et lui-même peuvent y répondre. si un autre utilisateur répond, je voudrais également sortir ses détails.

alt text

Répondre

1

Je ne pense pas que vous ayez besoin de 2 tables.

Utilisez une table de messages unique et créez 2 modèles qui utilisent tous les deux cette table.

I.E table = messages, Models = ProfileMessage, ProfileReply 

In that table make sure there is a profile_id, a user_id 
and a parent_id. Default all of these to null. 

Relate the ProfileMessage as 
    belongsTo User, 
    belongsTo Profile, 
    hasMany ProfileReply 

Relate the ProfileReply as 
    belongsTo ProfileMessage using the foreignKey key in the association to make sure you reference the parent_id and profile_id, 
    belongsTo User 

Ensuite, vous pouvez simplement interroger le ProfileMessage et il doit montrer tous les enfants objets ProfileReply comme si elles venaient d'une table liée séparée. Fondamentalement, une structure arborescente à un seul niveau relie les entrées à leurs entrées parentes dans la même table.

+0

J'ai essayé de le faire. mais je reçois une erreur en disant que la table profile_reply n'est pas trouvée :( –

+0

Vous devez définir le ProfileReply pour utiliser la table des messages http://book.cakephp.org/view/1059/useTable –

+0

cool ça marche: D je suis Quand les ProfileMessages sont tirés, comment puis-je m'assurer que id = pid seulement ces ProfileMessages.et quand le recurvise est augmenté pour tirer ProfileReply il tire également le ProfileMessage sous la réponse. –

1

Utilisez le comportement maîtrisable dans le modèle public $actsAs = array('Containable');

Puis, à partir du contrôleur de l'utilisateur:

$userWithMessagesAndReplies = $this->User->find('first' => array(
     'conditions' => array(/* conditions for finding the user (User.id) */), 
     'contain' => array(
      'StatusMessage' => array('StatusReply') 
     ) 
    ) 
); 

Ceci est juste un exemple. Selon l'endroit où vous faites la recherche, vous devez modifier légèrement le code ci-dessus. Je recommanderais de renvoyer les résultats de la recherche d'une méthode de modèle au lieu d'un contrôleur afin qu'il soit réutilisable. (J'ai utilisé un exemple de contrôleur pour faciliter la compréhension.)

+0

Je reçois cette erreur Le modèle "User" n'est pas associé au modèle "User" [CORE \ cake \ libs \ model \ comportements \ containable.php, ligne 363] quand je fais ceci $ status = $ this-> User -> StatusMessage-> find ('first', array ('contain' => array ('StatusMessageReply' => array ('Utilisateur' => array ('condition' => array ('User.id' => 1)))))); –

+0

Semble que vous faites la recherche à partir d'une méthode dans votre modèle utilisateur. Le code ci-dessus suppose que c'est dans le contrôleur. Pour le modèle, faites la même chose, mais au lieu de '$ this-> User-> find', utilisez simplement' $ this-> find' – Stephen

+0

Oh, attendez ... D'où faites-vous votre appel? – Stephen

1

Si vous voulez un système de commentaire fileté, vous devriez envisager d'utiliser le comportement Tree ou MultiTree, avec find('threaded').

+1

Vous avez raison, cela pourrait être utile s'il décide d'utiliser des threads profonds, mais pour une approche avec un seul enfant, c'est un peu trop. Dans le document CakePHP Docs for the Tree Behavior: 'Pour les petits arbres de données ou lorsque les données ne sont que de quelques niveaux, il est simple d'ajouter un champ parent_id à votre table de base de données et de l'utiliser pour savoir quel élément est le parent de quoi. » – Stephen