cakephp 使用相关模型的搜索条件
我在处理根据不同但相关的表上的搜索条件获取项目列表时遇到一个持续的问题。我需要清楚地知道如何处理这种情况。这是我最简单的例子:
如果我有一个代理模型(使用名为引用的表,其主键为 r_num 和使用名为代理的表的代理模型,代理表包含链接到代理的外键 r_num,代理可以有许多代理:
表:推荐
r_num int -- primary key auto incremented
r_company varchar(50) -- the name of the agency
... other fields don't matter
表:代理
a_num int -- primary key auto incremented
r_num int -- foreign key to the referral table
a_lname varchar(50) -- agent's last name
a_fname varchar(50) -- agent's first name
a_email varchar(50) -- agent's email
模型:
class Agency extends AppModel {
var $name = 'Agency';
var $useTable = 'referral';
var $primaryKey = 'r_num';
var $hasMany = array(
'Agent' => array(
'className' => 'Agent',
'foreignKey' => 'r_num',
'order' => 'Agent.a_lname DESC',
'dependent'=> true
)
);
}
class Agent extends AppModel {
var $name = 'Agent';
var $primaryKey = 'a_num';
}
我想要的只是使用 $this->Agency- 返回一个列表>find('all') 使用搜索表单中的条件,其中包括代理名字、代理姓氏、代理电子邮件。我需要代理公司名称和 ID 列表,但搜索条件基于我拥有的代理。几个不同的模型都会使用它,所以我需要关于它如何工作的文档,根据我在网上找到的内容,这是在 AgencyController 中工作的,但它是一个在某些情况下不起作用的黑客。我的更复杂的情况:我需要在不进行多次调用的情况下执行此操作,因为我的一些表将返回大量行,并且在这些查询上使用此技术需要几分钟。
class AgenciesController extends AppController {
var $helpers = array ('Html','Javascript', 'Form', 'Paginator', 'Ajax', 'Phoneformat');
var $name = 'Agencies';
var $components = array('RequestHandler', 'RentalValidation');
var $uses = array('Agency', 'Agent');
function index() {
$criteria = $this->postConditions($this->data);
if (empty($criteria)){
$arrArgs = $this->passedArgs;
unset($arrArgs['page']);
$criteria = $arrArgs;
}
$searchcriteria = array();
foreach (array('Agency.r_state', 'Agency.r_company') as $item ) {
$itemvalue = '';
if (isset($criteria[$item])){
$itemvalue = $criteria[ $item];
if (!empty($itemvalue)) {
$searchcriteria[$item . " LIKE "] = '%' . $itemvalue .'%';
}
}
}
foreach (array('Agent.a_lname', 'Agent.a_email') as $item ) {
$itemvalue = '';
if (isset($criteria[$item])){
$itemvalue = $criteria[ $item];
if (!empty($itemvalue)) {
$agent_rnums = $this->Agent->find('list',
array('conditions' =>
array($item . " LIKE " => '%'. $itemvalue .'%'),
'fields' => 'Agent.r_num'));
$searchcriteria['r_num'] = $agent_rnums;
}
}
}
$this->set('passedCriteria', $criteria);
$data = $this->paginate('Agency', $searchcriteria);
if (count($data) == 1) {
$referralid = $data[0]['Agency']['id'];
$this->redirect(array('action' => 'edit', $referralid));
}
$this->set('agencies', $data);
}
}
I'm having an ongoing issue with dealing with getting lists of items based on search criteria on different but related tables. I need to have a clear idea of how to deal with this type of situation. Here is my simplest example:
if I have an Agency Model (using a table called referral with a primary key of r_num and an Agent Model using a table called agents, the agents table contains a foreign key of r_num linking to the Agencies, The agency can have many Agents:
Table: referral
r_num int -- primary key auto incremented
r_company varchar(50) -- the name of the agency
... other fields don't matter
Table: agents
a_num int -- primary key auto incremented
r_num int -- foreign key to the referral table
a_lname varchar(50) -- agent's last name
a_fname varchar(50) -- agent's first name
a_email varchar(50) -- agent's email
Models:
class Agency extends AppModel {
var $name = 'Agency';
var $useTable = 'referral';
var $primaryKey = 'r_num';
var $hasMany = array(
'Agent' => array(
'className' => 'Agent',
'foreignKey' => 'r_num',
'order' => 'Agent.a_lname DESC',
'dependent'=> true
)
);
}
class Agent extends AppModel {
var $name = 'Agent';
var $primaryKey = 'a_num';
}
All I want is to return a list using $this->Agency->find('all') using conditions from a search form, which includes agent first name, agent last name, agent email. I need a list of Agency company names and ids but the search criteria is based on the agents. I have several different models that will use this, so I need documentation on how this can work. What I've tried based on what I've found online is this in the AgencyController which works but it is a hack that won't work on some of my more complicated cases: I need to do this without making multiple calls, since some of my tables will return huge numbers of rows, and using this technique on those queries takes several minutes.
class AgenciesController extends AppController {
var $helpers = array ('Html','Javascript', 'Form', 'Paginator', 'Ajax', 'Phoneformat');
var $name = 'Agencies';
var $components = array('RequestHandler', 'RentalValidation');
var $uses = array('Agency', 'Agent');
function index() {
$criteria = $this->postConditions($this->data);
if (empty($criteria)){
$arrArgs = $this->passedArgs;
unset($arrArgs['page']);
$criteria = $arrArgs;
}
$searchcriteria = array();
foreach (array('Agency.r_state', 'Agency.r_company') as $item ) {
$itemvalue = '';
if (isset($criteria[$item])){
$itemvalue = $criteria[ $item];
if (!empty($itemvalue)) {
$searchcriteria[$item . " LIKE "] = '%' . $itemvalue .'%';
}
}
}
foreach (array('Agent.a_lname', 'Agent.a_email') as $item ) {
$itemvalue = '';
if (isset($criteria[$item])){
$itemvalue = $criteria[ $item];
if (!empty($itemvalue)) {
$agent_rnums = $this->Agent->find('list',
array('conditions' =>
array($item . " LIKE " => '%'. $itemvalue .'%'),
'fields' => 'Agent.r_num'));
$searchcriteria['r_num'] = $agent_rnums;
}
}
}
$this->set('passedCriteria', $criteria);
$data = $this->paginate('Agency', $searchcriteria);
if (count($data) == 1) {
$referralid = $data[0]['Agency']['id'];
$this->redirect(array('action' => 'edit', $referralid));
}
$this->set('agencies', $data);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你就不能用另一种方式做吗?
,这样就只有 2 个 sql 调用
Couldn't you do it the other way?
that way there would be only 2 sql calls