cakephp 使用相关模型的搜索条件

发布于 2024-10-17 17:17:12 字数 3128 浏览 2 评论 0原文

我在处理根据不同但相关的表上的搜索条件获取项目列表时遇到一个持续的问题。我需要清楚地知道如何处理这种情况。这是我最简单的例子:

如果我有一个代理模型(使用名为引用的表,其主键为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

转身泪倾城 2024-10-24 17:17:12

你就不能用另一种方式做吗?

  • 获取所有符合所需条件的代理
  • 执行 Set::combine 来获取 Agency_ids(并使其唯一)
  • 使用 IN Agency_ids 进行查询

,这样就只有 2 个 sql 调用

Couldn't you do it the other way?

  • Get all Agents matching the desired conditions
  • do a Set::combine to get the agency_ids (and have it uniquified)
  • do query with IN agency_ids

that way there would be only 2 sql calls

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文