我使用的是 CakePHP 2.X 版
每次我在一个项目中执行此操作时,我总是会花费数小时来弄清楚如何使用 CakeDC 搜索行为来完成它,所以我写了这篇文章,试图用简单的语言提醒自己我需要做什么。我还注意到,尽管 Michael 总体上是正确的,但没有任何解释使得将其修改为自己的项目变得更加困难。
当您有一个“拥有并属于多个”关系并且您想要搜索连接表时,即其中包含两个字段的表,它将其两侧的表以多对-的方式连接在一起许多关系,您想要创建一个子查询,其中包含来自关系中的一个表的 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
如果 ArosHandover 中的所有记录的 aro_id 为 3,则将选择它们,然后 Handover.id 用于决定选择哪些 Handover 记录。
关于如何使用 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 创建一个子查询 sn-p 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
如果您想进一步解释我为什么做某事,请询问,如果我收到一封电子邮件告诉我您已经询问过,如果可以的话,我会给出答复。