критерий поиска CakePHP с использованием связанных моделей - PullRequest
1 голос
/ 16 февраля 2011

У меня постоянно возникает проблема с получением списков предметов на основе критериев поиска в разных, но связанных таблицах. Мне нужно иметь четкое представление о том, как справиться с такой ситуацией. Вот мой самый простой пример:

если у меня есть модель агентства (использующая таблицу с названием «переход» с первичным ключом 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'), используя условия из формы поиска, которая включает имя агента, фамилию агента, электронную почту агента. Мне нужен список названий компаний и идентификаторов агентства, но критерии поиска основаны на агентах. У меня есть несколько разных моделей, которые будут использовать это, поэтому мне нужна документация о том, как это может работать. На основании того, что я нашел в Интернете, я попытался сделать это в 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);
   }    
}

1 Ответ

0 голосов
/ 18 февраля 2011

Не могли бы вы сделать это по-другому?

  • Получить все агенты, соответствующие желаемым условиям
  • сделать Set :: объединить, чтобы получить agency_ids (и сделать его уникальным)
  • сделать запрос с IN agency_ids

таким образом, будет только 2 вызова sql

...