我正在使用 CakePHP 搜索插件,但有些东西我无法使用。我想要一个搜索字段(我们称之为 age),用户可以在其中输入一个值(例如 24),并获得结果中表的 age 字段中具有值的所有元素24 岁或以上的人。我怎样才能做到这一点?
到目前为止,我可以执行正常搜索,例如按名称或按精确值(如果您想要年龄精确那么它工作正常)。
这是我迄今为止拥有的与搜索插件相关的代码:
-型号:
class Person extends AppModel{
var $name = 'Person';
public $actsAs = array('Searchable');
public $filterArgs = array(
array('name' => 'name', 'type' => 'like'),
array('name' => 'age', 'type' => 'value'),
);
}
- 控制器:
class PersonsController extends AppController {
var $name = 'Persons';
var $components = array('Search.Prg');
public $presetVars = array(
array('field' => 'name', 'type' => 'value'),
array('field' => 'age', 'type' => 'value'),
);
function index() {
$this->set('persons', $this->Person->find('all'));
}
/* ---------------- SEARCH PLUGIN --------------*/
public function find() {
$this->Prg->commonProcess();
$this->paginate['conditions'] = this->Game->parseCriteria($this->passedArgs);
$this->set('persons', $this->paginate());
}
}
- find.ctp:
//apart from the code below, I have all the code to show the results
echo $form->create('Game', array(
'url' => array_merge(array('action' => 'find'), $this->params['pass'])
));
echo $form->input('name', array('div' => false));
echo $form->input('age', array('div' => false));
echo $form->submit(__('Search', true), array('div' => false));
echo $form->end();
总结一下:使用上面的代码,我可以搜索 age 字段的精确值。如何更改它以执行“年龄 >= 输入的值”的搜索?
提前非常感谢您!
这就是我解决它的方法(或者至少它似乎适用于我迄今为止所做的所有测试):
通过模型中 filterArgs 数组中的以下行更改了“年龄”行:
array('name' => 'age', 'type' => 'query', 'method' => 'findByAge', 'field' => 'Person.age'),
在同一模型中添加了以下方法:
public function findByAge($data = array()) {
$query = array(
'Person.age >=' => $data['age'],
);
return $query;
}
就是这样!使用“查询”类型,可以使用方法将任何复杂查询添加到主查询中。感谢 satyrwilder 指出了正确的方向!
来自您的预设变量 -
array('field' => 'age', 'type' => 'value'),
-- 从 commonProcess() 方法过滤到 find() 方法,我认为该方法构造了一个通用的查找,如条件=>数组($key=>$val)?
Cake 将数组 key=>val 对赋值视为生成“WHERE $key=$val”条件的指示。
要进行模糊拉动,无论您在何处构建通用 find() - 添加一个方法或其他东西只是将这两个滚动到
'conditions'=>array("name LIKE '%{$name}%'", "{$age}>={$val}")
或者任何你正在进行的事情。 将参数串在一起以获得对查询的预期效果,我相信您可以根据需要推断出进一步的方法来抽象该查询。
如果您需要更复杂的解决方案,Cake提供了优雅的内置、极其强大的子查询生成。看起来您正在非常努力地实现很多内置功能,但话又说回来,我不知道你的情况有多复杂。
http://book.cakephp.org/view/1030/Complex-Find-Conditions
HTH
我知道这个问题已经得到解答,但还有另一种方法可能更适合这种情况。
来自文档
“表达式”类型:如果您想添加将通过某种方法生成的条件,并且条件字段包含多个参数(如前面用于“范围”的示例中所示),则非常有用。这里的字段包含'Article.views BETWEEN ?和 ?'和 Article::makeRangeCondition 返回两个值的数组。
我必须完成与你相同的事情,但涉及 5 个不同的领域。我不想为每个查询都编写一个查询。以下是我如何使用表达式类型完成同样的事情。这是在filterArgs数组中。
array(
'name'=>'bathrooms',
'type'=>'expression',
'method'=>'returnNumber',
'field'=>'House.bathrooms >= ?'
)
然后我在模型中创建了这个函数,它只返回用户提交的数字。调用时,returnNumber 将传递两个数组。
看起来像这样。
Array
(
[0] => Array
(
[bathrooms] => 6
[bedrooms] => 5
[acres] => 12
[city] => Greenville
[year] => 2009
)
[1] => Array
(
[name] => bathrooms
[type] => expression
[method] => returnNumber
[field] => House.bathrooms >= ?
)
)
现在来看看实际的功能。您可以使用调试语句来查看您实际传递的函数的内容。
function returnNumber($arg, $name){
// debug(func_get_args());
// exit;
return $arg[$name['name']];
}