2016-05-30 7 views
1

私の必要条件は、Vets and Clinicsという2つの異なるテーブルで検索することです。それらの間には関係があるかもしれません。つまり、診療所に名前をつけて「a」を、その中に「a」を持つ獣医を持ってくるべきです。獣医は診療所に関連しているかもしれないし、そうでないかもしれない。現在、私は次のことをしています。 2つのクエリを実行しないようにする方法はありますか?これはcakephpのページネーションヘルパーの使用にも役立ちますか?cakephpの複数のモデルでの単一ページ設定

$this->paginate = array(
     'Vet' => array(
      'conditions' => $conditions, 
      'fields' => array('Vet.id', 'Vet.name', 'Vet.professionnal_address', 'phone_number', 'Vet.email', 'Vet.type', 'Vet.latitude', 'Vet.longitude','Vet.city','Vet.clinic_id','Vet.zipcode'), 
      'joins' => array( 
       array(
        'table' => 'vet_appointment_types', 
        'alias' => 'VetAppointmentType', 
        'type' => 'LEFT', 
        'conditions' => array(
         'Vet.id = VetAppointmentType.vet_id', 
        ) 
       ) 
      ), 
      'limit' => $limit, 
      'group' => array(
       'Vet.id' 
      ), 
      'order' => array(
       'Vet.name' => 'ASC' 
      ) 
     ), 
     'Clinic' => array(
      'conditions' => $conditions1, 
      'fields' => array('Clinic.*'), 
      'limit' => $limit, 
      'order' => array(
       'Clinic.name' => 'ASC' 
      ) 
     ) 
    ); 

$results = $this->paginate('Vet'); 
$results2 = $this->paginate('Clinic'); 

私は組合を使用することができない非データベースモデルのデフォルトのページネーションの成分を拡張し、ビット複雑で組合が、データベース構造を使用してみました。また、私は一時的なテーブルベースのモデルを実装することはオプションになると思うが、それは検索に使用されるので、それを実装する方法を正確に考えると、私は考えることができない。任意のヘルプは+1されます;)

+1

あなたは労働組合やビューを使用できない場合は、2つのテーブルの非関連したデータをページ分割するために苦労しています。私はその目的のためにElastic Searchを使用して検索インデックスを実装します。 – burzum

+0

テーブルとテーブルの両方からデータを格納するためにテンポラリテーブルを使用するのであれば、面倒な方法でしょうか? – Sp0T

+0

データが変更された場合は、一時表を変更する必要があります。たぶんあなたはデータベースビューを調べるべきでしょうか?ありがとう。 – MBosman

答えて

0

提案通り、私はデータベースビューを使用してそれを達成しました。以下はコードです。どんな改善提案も高く評価されます。

// \app\Model\Search.php 
App::uses('ConnectionManager', 'Model'); 
App::uses('AppModel', 'Model'); 
App::uses('CakeLog', 'Log'); 

class Search extends AppModel { 

    public function __construct() { 
     parent::__construct(); 

     $connection = ConnectionManager::getDataSource('default'); 
     $return = $connection->execute("CREATE OR REPLACE VIEW `search` AS 
      SELECT Vet.id, (CONCAT(`Vet`.`fname` , ' ', `Vet`.`lname`)) AS name, 'vet' AS TYPE , Vet.latitude, Vet.longitude, Vet.zipcode, Vet.speciality FROM `db`.`vets` AS `Vet` 
      UNION 
      SELECT Clinic.id, Clinic.name, 'clinic' AS TYPE , Clinic.lat, Clinic.long, Clinic.zipcode, Clinic.address FROM `db`.`clinics` AS `Clinic`"); 
     $return = ($return == true)?'Search View created successfully on '.date('Y-m-d H:i:s'):$return; 
     CakeLog::write('search', $return); 
    } 

    public $useTable = 'search';// This model does not use a database table 
    public $primaryKey = 'id'; // Define primary key 
    public $useDbConfig = 'default'; // Define db 

} 

これは、モデルがコントローラにロードされたとき、model.Everytimeユーザーが何を検索している、ビューが更新された値をフェッチすることができるように交換/作成されます。これはcakephpの他のモデルとしても使用できます。また、virtualFieldもサポートしています。データベースビューのクエリを作成するには、以下のように使用したクエリビルダを使用することもできます。

$joins = array(
     array(
      'table' => 'vet_appointment_types', 
      'alias' => 'VetAppointmentType', 
      'type' => 'LEFT', 
      'conditions' => array(
       'Vet.id = VetAppointmentType.vet_id', 
      ) 
     ) 
    ); 

    $dbo = $this->Vet->getDataSource(); 
    $subQuery = $dbo->buildStatement(
     array(
      'fields' => array('Vet.id', 'Vet.name'), 
      'table' => $dbo->fullTableName($this->Vet), 
      'alias' => 'Vet', 
      'limit' => $limit, 
      'group' => array(
       'Vet.id' 
      ), 
      'order' => array(
       'Vet.name' => 'ASC' 
      ), 
      'offset' => null, 
      'joins' => $joins, 
      'conditions' => $conditions 
     ), 
     $this->Vet 
    ); 
    $query = $subQuery; 

    $query .= ' UNION '; 

    $dbo = $this->Clinic->getDataSource(); 
    $subQuery = $dbo->buildStatement(
     array(
      'fields' => array('Clinic.id', 'Clinic.name'), 
      'table' => $dbo->fullTableName($this->Clinic), 
      'alias' => 'Clinic', 
      'limit' => $limit, 
      'conditions' => $conditions1, 
      'limit' => $limit, 
      'order' => array(
       'Clinic.name' => 'ASC' 
      ), 
      'offset' => null 
     ), 
     $this->Clinic 
    ); 

    $query .= $subQuery; 

    print_r($query); 
関連する問題