2013-05-13 42 views
2

我有一個'AddOns'的模型,它有一堆數據。我也有標籤,它們以通常的方式工作,只是就像在SO上一樣,從逗號分隔的列表中最多允許5個標籤。CakePHP - 將兩個表手動鏈接在一起(向HABTM鏈接表中添加一個字段)

我試圖創建的行爲如下:

  • 用戶創建上添加
  • 添加上創建
  • 系統分裂標記成一個陣列,並通過他們循環
  • 系統查找標記,如果存在,我們將使用該ID
  • 如果標記不存在,我們將創建它並使用該標識
  • 創建一個鏈接be補間的標籤和添加

我可以很容易地使用手動查詢,但我不知道這是最好的方法或我應該如何處理這個問題。這裏是我的代碼:

if ($this->request->is('post')) { 
$this->AddOn->create(); 
$this->AddOn->set('user_id', $this->Auth->user('id')); 
if ($this->AddOn->save($this->request->data)) { 

    // Get the ID of the addon 
    $addon_id = $this->AddOn->getInsertID(); 
    $tagsarr = explode(',', $this->request->data['Tag']['Tag']); 
    foreach($tagsarr as $tag){ 
     $tagdb = $this->Tags->findByTagName(trim($tag)); 
     if(!empty($tagdb)){ 
      // HELP! We have a tag, but how do we add the link? 
     } else { 
      // Add the tag, but then how do we link it? 
     } 
     unset($tagdb); 
    } 

    $this->Session->setFlash(
     __('The %s has been saved', __('add on'))   
    ); 
    $this->redirect(array('action' => 'index')); 
} else { 
    $this->Session->setFlash(
     __('The %s could not be saved. Please, try again.', __('add on')), 
    ); 
} 
} 

編輯:添加了一些我試圖實現的僞代碼。

$AddOn->create(); 
$AddOn->save(); // Create AddOn 
$AddOnID = $AddOn->insertId(); // Newly inserted AddOn's ID 

$tagsArr = explode(',', $post->tags); // Make an array of tags [this,is,a,tag,list] 
foreach($tagsArr as $tag){ // Loop through them 
    $tagFromDb = $Tags->findTagByName($tag); // Try and find the tag from the tags table 
    if(!$tagFromDb){ // Have we found it? No 
    $tagId = $Tags->newTag($tag); // Add it and reference 
    } else { // Have we found it? Yes 
    $tagId = $tagFromDb->id; // Reference it 
    } 
    $AddOnTagsLink->addAddOnTagsLink($AddOnID, $tagId); // Add the link 
} 
+0

您是否閱讀了本書中介紹如何保存HABTM數據的部分:http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasandbelongstomany-habtm你有,你有什麼嘗試? – Dave 2013-05-13 13:34:52

+0

我不確定那是我需要的。我希望在添加主記錄('addon')後創建鏈接,引用標記表中的標記ID(假設有一個)。我將用我想要實現的一些僞代碼更新這個問題 – Mike 2013-05-13 17:34:03

+0

@Dave - 我已經添加了僞代碼,可能更好地解釋我想要實現什麼。 – Mike 2013-05-13 17:41:07

回答

1

執行此操作的邏輯應該在模型中,而不是控制器中。使用before save回調允許我們在表單中添加「tags」字段並正常保存。

public function beforeSave($options = array()) { 
    if (isset($this->data['AddOn']['tags'])) { 
     $this->data['Tag'] = array(); 
     $submitted = array_map('trim', explode(',', $this->data['AddOn']['tags'])); 
     $existing = $this->Tag->find('list', array(
      'fields' => array('id', 'name'), 
      'conditions' => array('name' => $submitted), 
      'recursive' => -1 
     )); 
     foreach ($submitted as $tag) { 
      if(!empty($tag)) { 
       $id = array_search($tag, $existing); 
       if (!$id) { 
        $this->Tag->save(array('name' => $tag)); 
        $id = $this->Tag->id; 
       } 
       $this->data['Tag'][] = array('tag_id' => $id); 
      } 
     } 
    } 
    return true; 
} 

該代碼可以通過保存所有新標籤有一個查詢(使用saveAll),這將限制查詢三個數來提高(讓現有的,創建丟失,保存),而不是每個新的標籤之一,但這需要一些額外的工作handling returned IDs。如果您的用戶經常會創建大量新標籤,則應該這樣做。

+1

這是非常寶貴的。這是不正確的,我不得不作出一些修改 - 可能更多我描述不清的問題比你的答案,但它肯定有幫助,我現在完全理解這個問題(而不是複製和粘貼解決方案)。謝謝 – Mike 2013-05-15 12:52:27

+0

不客氣!我曾經有過類似的問題,所以我做了一些假設。現在你提到它,我看到你的表單必須有所不同,因爲提交的數據不完全相同。 – 2013-05-15 13:01:33