2010-08-24 24 views
0

我已經爲我的應用程序添加了cakePHP標記功能。我有一個名爲項目的表,可以有很多標籤關聯。所以我有一個帶有id和tag varchar字段的標籤表。包含標籤varchar字段的項目表,以及包含id,tag_id和project_id字段的鏈接表projects_tags。當我將標籤輸入添加到我的視圖中時,出於某種原因,存在的標籤會填充到下拉框中。任何人都可以弄清楚我在這裏做錯了什麼?CakePHP輸入是錯誤的輸入類型。應該是文本字段,但是是下拉菜單:S

這裏是我的標籤型號:

<?php 
class ProjectTag extends AppModel { 
var $name = 'ProjectTag'; 


var $hasAndBelongsToMany = array('Tag' => 
          array('className' => 'Tag', 
           'joinTable' => 'tags', 
           'foreignKey' => 'tag_id', 
           'conditions' => '', 
           'order'  => '', 
           'limit'  => '', 
           'unique'  => true, 
           'finderQuery' => '', 
           'deleteQuery' => '', 
          ), 
          array('className' => 'Project', 
           'joinTable' => 'projects', 
           'foreignKey' => 'project_id', 
           'conditions' => '', 
           'order'  => '', 
           'limit'  => '', 
           'unique'  => true, 
           'finderQuery' => '', 
           'deleteQuery' => '', 
          ) 

          ); 

} 

?> 

這裏是我的附加項目視圖add.ctp:

<?php 
echo $form->create('Project'); 
echo $form->input('title', array('label' => 'Title')); 
echo $form->input('website', array('label' => 'Website')); 
echo $form->input('description', array('label' => 'Description')); 
echo $form->input('language_id', array('label' => 'Language')); 
echo $form->input('tags'); 
echo $form->end('Post project'); 
?> 

這裏是標籤的行爲模式:

<?php 

class TagBehavior extends ModelBehavior { 
/** 
* Initiate behaviour for the model using specified settings. 
* 
* @param object $model Model using the behaviour 
* @param array $settings Settings to override for model. 
* 
* @access public 
*/ 
function setup(&$model, $settings = array()) { 


    $default = array('table_label' => 'tags', 'tag_label' => 'tag', 'separator' => ','); 

    if (!isset($this->settings[$model->name])) { 
     $this->settings[$model->name] = $default; 
    } 

$this->settings[$model->name] = array_merge($this->settings[$model->name], ife(is_array($settings), $settings, array())); 

} 

/** 
* Run before a model is saved, used to set up tag for model. 
* 
* @param object $model Model about to be saved. 
* 
* @access public 
* @since 1.0 
*/ 
function beforeSave(&$model) { 
// Define the new tag model 
$Tag =& new Tag; 
    if ($model->hasField($this->settings[$model->name]['table_label']) 
    && $Tag->hasField($this->settings[$model->name]['tag_label'])) { 


    // Parse out all of the 
    $tag_list = $this->_parseTag($model->data[$model->name][$this->settings[$model->name]['table_label']], $this->settings[$model->name]); 
    $tag_info = array(); // New tag array to store tag id and names from db 
    foreach($tag_list as $t) { 
     if ($res = $Tag->find($this->settings[$model->name]['tag_label'] . " LIKE '" . $t . "'")) { 
      $tag_info[] = $res['Tag']['id']; 
     } else { 
      $Tag->save(array('id'=>'',$this->settings[$model->name]['tag_label']=>$t)); 
      $tag_info[] = sprintf($Tag->getLastInsertID()); 
     } 
     unset($res); 
    } 

    // This prepares the linking table data... 
    $model->data['Tag']['Tag'] = $tag_info; 
    // This formats the tags field before save... 
    $model->data[$model->name][$this->settings[$model->name]['table_label']] = implode(', ', $tag_list); 
} 
return true; 
} 


/** 
* Parse the tag string and return a properly formatted array 
* 
* @param string $string String. 
* @param array $settings Settings to use (looks for 'separator' and 'length') 
* 
* @return string Tag for given string. 
* 
* @access private 
*/ 
function _parseTag($string, $settings) { 
    $string = strtolower($string); 

    $string = preg_replace('/[^a-z0-9' . $settings['separator'] . ' ]/i', '', $string); 
    $string = preg_replace('/' . $settings['separator'] . '[' . $settings['separator'] . ']*/', $settings['separator'], $string); 

$string_array = preg_split('/' . $settings['separator'] . '/', $string); 
$return_array = array(); 

foreach($string_array as $t) { 
    $t = ucwords(trim($t)); 
    if (strlen($t)>0) { 
     $return_array[] = $t; 
    } 
} 

    return $return_array; 
} 
} 

?> 

這裏my project_controller add:

function add() { 


    $this->set("Languages", $this->Project->Language->find("list")); 


    if (!empty($this->data)) { 
     if ($this->Project->save($this->data)) { 
      $this->Session->setFlash('Project added.'); 
      $this->redirect(array('action' => 'index')); 
     } 
    } 
} 

回答

1

cdburgess是正確的關於下拉正在出現的原因,但是你可以重寫合理的默認通過調整蛋糕「魔術」字段來滿足自己的要求:

echo $form->input('tags', array('type' => 'text')); 

我不會被罵語法,但是這會將標籤輸入創建爲文本框。

國際海事組織,這是一個更好的選擇,而不是放棄一個在其他地方有如此強大力量的協會。

+0

感謝羅布這工作的一種享受。我不得不保持我的關係,因爲我在這裏使用多個模型,並使用鏈接表...謝謝 – iamjonesy 2010-08-24 15:36:33

+0

很高興它解決了。關聯對於Cake,Rails等的魔力來說非常重要,在幾乎所有情況下,刪除它們都是最後的選擇。 – 2010-08-24 18:12:07

1

這是因爲模型中的關係。 CakePHP將自動關聯標籤併爲您創建一個下拉菜單。這是擁有相關領域的目的。它基本上是說,「這個標籤需要是存在於'標籤'表中的東西。」因此它會使用來自標籤的數據預填充它。

取出HABTM關係,它將返回到測試框。

+0

似乎已經奏效!謝謝!現在我已經刪除了關係,它如何將標籤與項目綁定? – iamjonesy 2010-08-24 14:54:38

+0

您可以在不同的模型中創建關係。但是你需要問自己更多的是圍繞設計。你想如何使用這個領域?如果你能解釋你想要完成的是什麼,那麼解釋如何配置關係會更容易。 – 2010-08-24 15:07:00

相關問題