2011-08-11 1 views
0

最後の2日間、cakephpでページネーションの問題の解決策を探していました。cakephp:ページ区切りのメソッドをオーバーライドするためのモデルクラスを拡張する

要するに、私は同じモデルのために異なるページ分割方法が必要です。インデックスアクションはデフォルトメソッドを使用し、ビューアクションはカスタムクエリを使用してメソッドを使用します。

OOPの継承コンセプトに基づいて、解決策は私のモデルを拡張し、拡張モデルのページネーション方法をオーバーライドすることだと思いました。したがって、私は、コントローラから、インデックスアクションのデフォルトのページネーションメソッドと、ビューアクションのカスタムメソッドを呼び出すことができます。

質問は次のとおりです。モデルクラスを拡張するにはどうすればよいですか?このイデアはうまくいくのだろうか?

これは私のモデルである:

<?php 
class Communication extends AppModel { 

var $name = 'Communication'; 
var $displayField = 'title'; 

//The Associations below have been created with all possible keys, those that are not needed can be removed 

var $hasMany = array(
    'Interaction' => array(
     'className' => 'Interaction', 
     'foreignKey' => 'communication_id', 
     'dependent' => false, 
     'conditions' => '', 
     'fields' => '', 
     'order' => '', 
     'limit' => '', 
     'offset' => '', 
     'exclusive' => '', 
     'finderQuery' => '', 
     'counterQuery' => '' 
    ), 
    'Star' => array(
     'className' => 'Star', 
     'foreignKey' => 'communication_id', 
     'dependent' => false, 
     'conditions' => '', 
     'fields' => '', 
     'order' => '', 
     'limit' => '', 
     'offset' => '', 
     'exclusive' => '', 
     'finderQuery' => '', 
     'counterQuery' => '' 
    ) 
); 

var $hasAndBelongsToMany = array(
    'Document' => array(
     'className' => 'Document', 
     'joinTable' => 'communications_documents', 
     'foreignKey' => 'communication_id', 
     'associationForeignKey' => 'document_id', 
     'unique' => true, 
     'conditions' => '', 
     'fields' => '', 
     'order' => '', 
     'limit' => '', 
     'offset' => '', 
     'finderQuery' => '', 
     'deleteQuery' => '', 
     'insertQuery' => '' 
    ), 
    'Event' => array(
     'className' => 'Event', 
     'joinTable' => 'communications_events', 
     'foreignKey' => 'communication_id', 
     'associationForeignKey' => 'event_id', 
     'unique' => true, 
     'conditions' => '', 
     'fields' => '', 
     'order' => '', 
     'limit' => '', 
     'offset' => '', 
     'finderQuery' => '', 
     'deleteQuery' => '', 
     'insertQuery' => '' 
    ), 
    'Meeting' => array(
     'className' => 'Meeting', 
     'joinTable' => 'communications_meetings', 
     'foreignKey' => 'communication_id', 
     'associationForeignKey' => 'meeting_id', 
     'unique' => true, 
     'conditions' => '', 
     'fields' => '', 
     'order' => 'date_create DESC', 
     'limit' => '', 
     'offset' => '', 
     'finderQuery' => '', 
     'deleteQuery' => '', 
     'insertQuery' => '' 
    ), 
    'User' => array(
     'className' => 'User', 
     'joinTable' => 'communications_users', 
     'foreignKey' => 'communication_id', 
     'associationForeignKey' => 'user_id', 
     'unique' => true, 
     'conditions' => '', 
     'fields' => '', 
     'order' => 'name', 
     'limit' => '', 
     'offset' => '', 
     'finderQuery' => '', 
     'deleteQuery' => '', 
     'insertQuery' => '' 
    ) 
); 

function getComInfos($id) { 

    $this->unbindModel(array('hasAndBelongsToMany'=>array('Document','Event','Meeting'))); 
    $this->unbindModel(array('hasMany'=>array('Star','Interaction'))); 
    $communication_infos = $this->read(null, $id); 

    //debug($communication_infos); 

    return $communication_infos; 

} 

function getComLinks($id) { 

    $communication_links = $this->query(" 
    SELECT 'documents' AS 'type', 'D' AS 'marker', d.id AS id, d.date_create AS date, du.user_id AS info_aux, d.title AS title, d.desc AS content 
    FROM communications_documents AS cd 
    JOIN documents AS d ON d.id = cd.document_id 
    JOIN documents_users AS du ON du.document_id = d.id 
    WHERE cd.communication_id = ".$id." 

    UNION 

    SELECT 'events' AS 'type', 'E' AS 'marker', e.id AS id, e.date_create AS date, e.institution AS info_aux, e.title AS title, e.desc AS content 
    FROM communications_events AS ce 
    JOIN events AS e ON e.id = ce.event_id 
    WHERE ce.communication_id =".$id." 

    UNION 

    SELECT 'meetings' AS 'type', 'R' AS 'marker', m.id AS id, m.date_create AS date, m.site AS info_aux, m.title AS title, m.desc AS content 
    FROM communications_meetings AS cm 
    JOIN meetings AS m ON m.id = cm.meeting_id 
    WHERE cm.communication_id =".$id." 

    UNION 

    SELECT 'interactions' AS 'type', 'C' AS 'marker', i.id AS id, i.date_create AS date, i.user_id AS info_aux, i.title AS title, i.content AS content 
    FROM interactions AS i 
    WHERE i.communication_id =".$id." 

    ORDER BY date DESC 
    "); 

    //debug($communication_links); 

    return $communication_links; 

} 

} 

そして、これは私はちょうどビューのアクションに使用する必要があるというのが私の2つのカスタムページネーション方式、次のとおりです。コントローラで

function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()) { 

    $recursive = -1; 
    return $this->query(" 
    SELECT 'documents' AS 'type', 'D' AS 'marker', d.id AS id, d.date_create AS date, du.user_id AS info_aux, d.title AS title, d.desc AS content 
    FROM communications_documents AS cd 
    JOIN documents AS d ON d.id = cd.document_id 
    JOIN documents_users AS du ON du.document_id = d.id 
    WHERE cd.communication_id = 137 

    UNION 

    SELECT 'events' AS 'type', 'E' AS 'marker', e.id AS id, e.date_create AS date, e.institution AS info_aux, e.title AS title, e.desc AS content 
    FROM communications_events AS ce 
    JOIN events AS e ON e.id = ce.event_id 
    WHERE ce.communication_id =137 

    UNION 

    SELECT 'meetings' AS 'type', 'R' AS 'marker', m.id AS id, m.date_create AS date, m.site AS info_aux, m.title AS title, m.desc AS content 
    FROM communications_meetings AS cm 
    JOIN meetings AS m ON m.id = cm.meeting_id 
    WHERE cm.communication_id = 137 

    UNION 

    SELECT 'interactions' AS 'type', 'C' AS 'marker', i.id AS id, i.date_create AS date, i.user_id AS info_aux, i.title AS title, i.content AS content 
    FROM interactions AS i 
    WHERE i.communication_id = 137 

    ORDER BY date DESC 
    LIMIT ".(($page-1)*$limit).", ".$limit); 

} 

function paginateCount($conditions = null, $recursive = 0, $extra = array()) { 
    $sql = " 
    SELECT 'documents' AS 'type', 'D' AS 'marker', d.id AS id, d.date_create AS date, du.user_id AS info_aux, d.title AS title, d.desc AS content 
    FROM communications_documents AS cd 
    JOIN documents AS d ON d.id = cd.document_id 
    JOIN documents_users AS du ON du.document_id = d.id 
    WHERE cd.communication_id = 137 

    UNION 

    SELECT 'events' AS 'type', 'E' AS 'marker', e.id AS id, e.date_create AS date, e.institution AS info_aux, e.title AS title, e.desc AS content 
    FROM communications_events AS ce 
    JOIN events AS e ON e.id = ce.event_id 
    WHERE ce.communication_id = 137 

    UNION 

    SELECT 'meetings' AS 'type', 'R' AS 'marker', m.id AS id, m.date_create AS date, m.site AS info_aux, m.title AS title, m.desc AS content 
    FROM communications_meetings AS cm 
    JOIN meetings AS m ON m.id = cm.meeting_id 
    WHERE cm.communication_id = 137 

    UNION 

    SELECT 'interactions' AS 'type', 'C' AS 'marker', i.id AS id, i.date_create AS date, i.user_id AS info_aux, i.title AS title, i.content AS content 
    FROM interactions AS i 
    WHERE i.communication_id = 137 

    ORDER BY date DESC 
    "; 
    $this->recursive = $recursive; 
    $results = $this->query($sql); 
    return count($results); 
}` 

答えて

2

、私は設定します

class SampleController extends AppController { 
     ... 
     var $paginate = array(
      'ModelName' => array(...general options...) 
     ); 
     ... 
    } 

それぞれのモデルの非常に一般的なオプションですt:

... 
    function index(){ 
     $this->paginate = array(
      ... specific pagination options for index action ... 
     ); 
     $this->paginate('ModelName'); 
    } 
    ... 
    function view(){ 
     $this->paginate = array(
      ... specific pagination options for view action ... 
     ); 
     $this->paginate('ModelName'); 
    } 

このようにして、各操作ごとにカスタムページ付けの結果を表示できます。

希望に役立ちます。

+0

こんにちは@baseer、 あなたは正しいですが、私は同じモデルを使用する必要がありますか?インデックスアクションの場合は、デフォルトのクエリを使用してデフォルトのページネーションメソッドを使用します。ビューアクションのために、私はカスタムクエリを使用してカスタムテーブルを作成する方法が必要です。この方法では、一部のテーブルでUNIONを選択します。 –

+0

paginate()メソッドとpaginateCount()メソッドをオーバーライドする必要があります。まともな例があります:[カスタムクエリページネーション](http://book.cakephp.org/view/1237/Custom-Query-Pagination)。 どこかにpaginate()を入れます '$ results = $ this-> query($ sql);' ここで、SQLフラグメント '$ sql'は' $ limit'と '$ page ' '変数が渡されます(他のすべての変数と同様に)。 同じモデルの複数の改ページタイプの問題を解決するには、 '$ extra'変数を使用してそれらを区別することができます。 – Baseer

+0

Cool @baseer。しかし、この余分な仕事はどのようにして行われますか?私はこの使用法を見たことがありません。 –

関連する問題