2011-05-13 72 views
0

我正在使用CakePHP 1.3.8,並且已安裝CakeDC Search plugin。我有一個教程模型,它與LearningGoal模型處於HABTM關係中。將CakeDC搜索插件與相關模型配合使用

我在Tutorials控制器中有一個搜索動作&視圖,我可以在其中成功搜索教程模型中的字段。我還想在同一個表單上使用LearningGoal複選框過濾我的教程搜索結果。我試過向Tutorial的$ filterArgs和TutorialsController的$ presetVars添加各種參數。我也嘗試將相關的$ filterArgs移動到LearningGoal模型。我還沒有能夠成功觸發$ filterArgs中的學習目標條目。

我想我一定會錯過一些明顯的東西。或者,也許搜索插件不支持我想要做的。有誰知道如何使用這個插件來搜索相關模型?

回答

0

所以這裏是我想通了。您可以將下面的內容與搜索插件路線結合起來,以便在相關模型上進行搜索。

的$的filterExpr片在教程模型必須是這樣的:

var $filterArgs = array(
    array('name' => 'LearningGoal', 'type' => 'subquery', 'method' => 'findByLearningGoals', 'field' => 'Tutorial.id'), 
); 

這裏的教程模式的支持功能:

function findByLearningGoals($data = array()) { 
    $ids = explode('|', $data['LearningGoal']); 
    $ids = join(',', $ids); 
    $this->LearningGoalsTutorial->Behaviors->attach('Containable', array('autoFields' => false)); 
    $this->LearningGoalsTutorial->Behaviors->attach('Search.Searchable'); 

    $query = $this->LearningGoalsTutorial->getQuery('all', 
    array(
     'conditions' => array('LearningGoalsTutorial.learning_goal_id IN (' . $ids . ')'), 
     'fields' => array('tutorial_id'), 
    ) 
); 
    return $query; 
} 

在TutorialsController,$ presetVars應該是這樣的:

public $presetVars = array(
    array('field' => 'LearningGoal', 'type' => 'checkbox', 'model' => 'Tutorial'), 
); 

而在我在TutorialsController的搜索操作中,我做到了這一點:

$this->LearningGoal = $this->Tutorial->LearningGoal; 

Prg組件似乎需要它。

0

我使用CakePHP 2.x版本

我每次做這個項目中,我總是花時間搞清楚如何使用CakeDC搜索行爲做到這一點,所以我寫了這個嘗試,並提醒自己用簡單的語言我需要做什麼。我也注意到,雖然邁克爾通常是正確的,但沒有任何解釋讓它更難以修改爲自己的項目。

當你有一個「擁有並且屬於許多」關係,並且你想要搜索連接表時,也就是具有兩個字段的表格,它將兩邊的表格以多對多的方式連接在一起-many關係你想創建一個帶有關係表中某個表的ID列表的子查詢。來自關係另一側表中的ID將被檢查以查看它們是否在該記錄中,並且如果它們是那麼主表中的記錄將被選擇。如果它們具有爲3的aro_id則Handover.id用於決定要選擇的切換記錄

在下面的例子從ArosHandover

SELECT Handover.id, Handover.title, Handover.description 
FROM handovers AS Handover 
WHERE Handover.id in 
(SELECT ArosHandover.handover_id 
FROM aros_handovers AS ArosHandover 
WHERE ArosHandover.aro_id IN (3) AND ArosHandover.deleted != '1') 
LIMIT 20 

所有記錄將被選中。

關於如何使用CakeDC搜索行爲完成此操作。

首先,字段放入搜索表單:

echo $this->Form->create('Handover', array('class' => 'form-horizontal'));?> 
echo $this->Form->input('aro_id', array('options' => $roles, 'multiple' => true, 'label' => __('For', true), 'div' => false, true)); 

等...

通知我還沒有放置在窗體元件在ArosHandover數據空間;另一種說法是,當發送表單請求時,字段aro_id將被放置在名爲Handover的數組下。

在根據變量$的filterExpr模型:

'aro_id' => array('name' => 'aro_id', 'type' => 'subquery', 'method' => 'findByAros', 'field' => 'Handover.id') 

通知該類型是「子查詢」,因爲我上面提到你需要創建一個子查詢,以便能夠找到相應的記錄和將類型設置爲子查詢,您告訴CakeDC創建SQL的子查詢片段。該方法是將要編寫代碼的函數名稱。本場元件是要出現在例如查詢的該部分上面的字段的名稱

WHERE Handover.id in 

然後寫些將返回子查詢功能:

function findByAros($data = array()) 
    { 
    $ids = ''; //you need to make a comma separated list of the aro_ids that are going to be checked 
    foreach($data['aro_id'] as $k => $v) 
    { 
     $ids .= $v . ', '; 
    } 
    if($ids != '') 
    { 
     $ids = rtrim($ids, ', '); 
    } 
    //you only need to have these two lines in if you have not already attached the behaviours in the ArosHandover model file 
    $this->ArosHandover->Behaviors->attach('Containable', array('autoFields' => false)); 
    $this->ArosHandover->Behaviors->attach('Search.Searchable'); 

    $query = $this->ArosHandover->getQuery('all', 
     array(
     'conditions' => array('ArosHandover.aro_id IN (' . $ids . ')'), 
     'fields' => array('handover_id'), //the other field that you need to check against, it's the other side of the many-to-many relationship 
     'contain' => false //place this in if you just want to have the ArosHandover table data included 
     ) 
    ); 
    return $query; 
    } 

在切換控制器:

public $components = array('Search.Prg', 'Paginator'); //you can also place this into AppController 
public $presetVars = true; //using $filterArgs in the model configuration 
public $paginate = array(); //declare this so that you can change it 

// this is the snippet of the search form processing 
public function admin_find() 
    { 
    $this->set('title_for_layout','Find handovers'); 
    $this->Prg->commonProcess(); 
    if(isset($this->passedArgs) && !empty($this->passedArgs)) 
    {//the following line passes the conditions into the Paginator component 
     $this->Paginator->settings = array('conditions' => $this->Handover->parseCriteria($this->passedArgs)); 
     $handovers = $this->Paginator->paginate(); // this gets the data 
     $this->set('handovers', $handovers); // this passes it to the template 

如果您想進一步的解釋,爲什麼我做了什麼,問,如果我收到一封電子郵件,告訴我,你問我,我會給出一個答案 能夠。