2012-04-15 5 views
0

Ich habe folgendes Setup für meine CakePHP App:Speichern von Tags in einer Datenbanktabelle in CakePHP

Posts 
id 
title 
content 

Topics 
id 
title 

Topic_Posts 
id 
topic_id 
post_id 

Also im Grunde habe ich eine Tabelle von Themen (Tags), die alle einzigartig sind und eine ID haben. Und dann können sie angehängt werden, um sie mithilfe der Join-Tabelle Topic_Posts zu veröffentlichen. Wenn ein Benutzer einen neuen Beitrag erstellt, füllt er die Themen aus, indem er sie in ein durch ein Komma getrenntes Textfeld eingibt, das diese in der Tabelle "Topics" speichert, falls sie nicht bereits vorhanden sind, und die Verweise dann in der Tabelle "Topic_posts" speichern. Ich habe die oben wie so eingestellt Modelle:

Beitrag Modell:

class Post extends AppModel 
{ 
    public $name = 'Post'; 

    public $hasAndBelongsToMany = array(
     'Topic' => array('with' => 'TopicPost') 
    ); 
} 

Topic Modell:

class Topic extends AppModel 
{ 
    public $hasMany = array(
     'TopicPost' 
    ); 
} 

TopicPost Modell:

class TopicPost extends AppModel { 
    public $belongsTo = array(
     'Topic', 'Post' 
    ); 
} 

Und für die neue post-Methode I habe dies bisher:

public function add() 
{ 
    if ($this->request->is('post')) 
    { 
     //$this->Post->create(); 

     if ($this->Post->saveAll($this->request->data)) 
     { 

      // Redirect the user to the newly created post (pass the slug for performance) 
      $this->redirect(array('controller'=>'posts','action'=>'view','id'=>$this->Post->id)); 
     } 
     else 
     { 
      $this->Session->setFlash('Server broke!'); 
     } 
    } 
} 

Wie Sie sehen können, habe ich saveAll verwendet, aber wie gehe ich mit den Themendaten um?

Ich habe gesehen, Dinge wie: http://bakery.cakephp.org/articles/dooltaz/2007/05/02/simple-tagging-behavior aber ich suche diese viel einfacher und moderner machen (diese Artikel Daten 2007), und ich bin auch mit CakePHP 2.1

Antwort

3

Ich würde eine Methode implementieren, in Thema (Modell) wie folgt:

/** 
* This methods saves the topics coming from a post save and associates them with the right post. 
* 
* @param string $postId The post id to save associations to. 
* @param string $topics A comma seperated list of topics to save. 
* @param bool Save of all topics succeeded (true) or not (false). 
*/ 
    public function savePostTopics($postId, $topics){ 
     // Explode the topics by comma, so we have an array to run through 
     $topics = explode(',', $topics); 
     // Array for collecting all the data 
     $collection = array(); 

     foreach($topics as $topic){ 
      // Trim it so remove unwanted white spaces in the beginning and the end. 
      $topic = trim($topic); 

      // Check if we already have a topic like this 
      $controlFind = $this->find(
       'first', 
       array(
        'conditions' => array(
         'title' => $topic 
        ), 
        'recursive' => -1 
       ) 
      ); 

      // No record found 
      if(!$controlFind){ 
       $this->create(); 
       if(
        !$this->save(
         array(
          'title' => $topic 
         ) 
        ) 
       ){ 
        // If only one saving fails we stop the whole loop and method. 
        return false; 
       } 
       else{ 
        $temp = array(
         'TopicPost' => array(
          'topic_id' => $this->id, 
          'post_id' => $postId 
         ) 
        ) 
       } 
      } 
      else{ 
       $temp = array(
        'TopicPost' => array(
         'topic_id' => $controlFind['Topic']['id'], 
         'post_id' => $postId 
        ) 
       ) 
      } 
      $collection[] = $temp; 
     } 

     return $this->TopicPost->saveMany($collection, array('validate' => false)); 
    } 

Ich habe es nicht getestet, aber es sollte funktionieren.

Sie würden dies nach dem Speichern des Posts selbst nennen und ihm die Post-ID und die Themen aus dem Daten-Array geben. Stellen Sie sicher, dass Sie die Rückgabe dieser Methode verarbeiten. Wenn das Speichern eines Themas fehlschlägt, ist das ein Grund, den gesamten Post zu löschen? Da es in CakePHP kein gutes Rollback-API gibt, müssen Sie den Eintrag ggf. aus der Datenbank löschen. Oder geben Sie dem Benutzer, der den Beitrag verfasst hat, einfach eine Erfolgsmeldung und protokolliert den Fehler?

Durch die Art und Weise: Die CakePHP Konventionen nach dem Vorbild und der Tisch für die Assoziation auch PostTopic und post_topic genannt werden müssen. Alphabetisch;) Möglicherweise möchten Sie es in diesem frühen Stadium Ihres Projekts ändern.

Grüße func0der

+0

Ehrfürchtig, die fein gearbeitet hat. Ich musste jedoch keinen meiner Tabellennamen oder Modellnamen ändern. Danke;) – Cameron

+0

Nein, du musst es nicht ändern. Aber nach den CakePHP-Konventionen solltest du;) Lies dies durch: http://book.cakephp.org/2.0/en/models/associations-linking-model-together.html#hasandbelongstomany-habtm (Die Infobox unter den Beispielen) – func0der

Verwandte Themen