質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.98%

cakephp での条件付きのpaginate()を行いたい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 5,851

hiro3333

score 12

こんにちは。

cakephpを使用して、条件付きの値を取得したいのですが、うまくできずに困っています。

行いたいことは、hasMany でアソシエーションしている別モデル(下記例ではReserveモデル)の
カラムに対して条件を付けたいです。

// ベースモデル
class Customer 
{
    var $hasMany = array(
        'Reserve'=>array(
            'className'=>'Reserve',
            'foreignKey' => 'customer_id',
        )
    );
}

// サブモデル
class Reserve {
    ....
}


// コントローラー
controller ...

$condition = array(
    'limit' => 20,
    'order' => array('Customer.id DESC'),
    'contain' => array(
        'Reserve'
        ),
    )
);

// ここに条件を追加したい
/**ここから******************************************************/

// 行いたいこと
上記の $condition'contain'しているモデルにwhere条件を付けたい
SQLの例)
select * from `Customer`
join `Reserve` on `Customer`.id = `Reserve`.customer_id
where `Reserve`.start >= NOW();

/**ここまで******************************************************/

$this->Customer = ClassRegistry::init('Customer');
$this->paginate=$condition;
$data = $this->paginate('Customer');
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+3

「hasMany先のテーブルに条件を指定してもメインテーブルの取得件数は変わらない、
なので結合後にhasMany先のテーブルの条件で絞りたい」ということでいいですかね?

JOINの後、WHEREで絞込を行います。
ReserveのデータはJOINで取得しているのでContainは空を指定して下さい。
代わりにfieldsで欲しいカラムを指定します。

// コントローラー
$condition = array(  'limit'      => 20
                   , 'order'      => array('Customer.id DESC')
                   , 'contain'    => array()
                   , 'fields'     => array('Customer.id', 'Reserve.id')
                   , 'conditions' => array('Reserve.start >= ?'  => date('Y-m-d H:i:s')) 
                   , 'joins'      => array(array(  'table'       => 'reserves'
                                                 , 'alias'       => 'Reserve'
                                                 , 'type'        => 'LEFT'
                                                 , 'conditions'  => array('Customer.id = Reserve.customer_id'))));

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

containでフィルタリングする方法はどうでしょう。

// 必要なフィールドとその値を指定
// 以下の場合は、idが1のものを取得
'contain' => array('Reserve.id = 1')

または、逆に、条件指定したい方のモデルにconditionsを付けてfindして、belongsToでアソシエーション先のデータを取ってあげるのも手ですね。

あと余計なことかもしれませんが、containを使う場合は、Containableビヘイビアをロードします。
そのアクションでのみ使うなら、$this->Customer->Behaviors->load('Containable');のようにロードします。
念のため。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる