我正在使用CakePHP 1.3.8,我已经安装了CakeDC Search plugin。我有一个Tutorial模型,它与LearningGoal模型处于HABTM关系。
我有一个搜索动作&在Tutorials控制器中查看,我可以使用它在Tutorial模型中成功搜索字段。我还想在同一表单上使用LearningGoal复选框过滤我的教程搜索结果。我已经尝试将各种参数添加到Tutorial的$ filterArgs和TutorialsController的$ presetVars中。我也尝试将相关的$ filterArgs移动到LearningGoal模型。我还没有能够成功触发$ filterArgs中的学习目标条目。
我想我一定错过了一些明显的东西。或者搜索插件可能不支持我想要做的事情。有谁知道如何使用这个插件搜索相关的模型?
答案 0 :(得分:0)
所以这就是我所知道的。您可以将以下内容与搜索插件方向结合起来搜索相关模型。
Tutorial模型中的$ filterArgs部分必须如下所示:
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组件似乎需要这样。
答案 1 :(得分:0)
我正在使用CakePHP版本2.X
每次我在一个项目中这样做时,我总是花费数小时来弄清楚如何使用CakeDC搜索行为来做到这一点,所以我写这篇文章试图用简单的语言提醒自己我需要做什么。我也注意到虽然迈克尔一般都是正确的,但没有任何解释,这使得将其修改为自己的项目变得更加困难。
如果你有一个“拥有并且属于许多”的关系,并且你想要搜索连接表,即其中包含两个字段的表,它们将它们的两侧的表连接在一起许多关系,您希望创建一个子查询,其中包含关系中其中一个表的ID列表。将检查关系另一侧的表中的ID以查看它们是否在该记录中,如果它们是,则将选择主表中的记录。
在以下示例中
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
如果AroHandover的aro_id为3,则会选择所有记录,然后Handover.id用于决定选择哪个切换记录。
关于如何使用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的数组下。
在变量$ filterArgs:
下的模型中'aro_id' => array('name' => 'aro_id', 'type' => 'subquery', 'method' => 'findByAros', 'field' => 'Handover.id')
注意类型是'子查询',如上所述,您需要创建子查询以便能够找到适当的记录,并通过将类型设置为子查询,告诉CakeDC创建SQL的子查询片段。该方法是将编写代码的函数名称。 field元素是将出现在
上面的示例查询的这一部分中的字段的名称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
如果你想进一步解释为什么我做了什么,请问,如果我收到一封电子邮件,告诉我你已经问过,如果我能够,我会给出答案。