CakePHPにページネーションを実装しようと思いましたが、2ページ目以降のリンクを押すと検索条件が保存されず上手く機能しません。
これは有名な不具合らしく、主な解決策は、セッションを用いて検索条件を保存する方法があるということなのですが。
今回は以下のサイトを参考にさせていただいています。
参考サイト:初めての[CakePHP2.x]での開発、そして挫折するまで日記~その27 検索結果をページネーションで表示させる
しかし、なぜかタイトルにある通り、セッションに書き込めない、もしくは読み込めない状態で解決策がわかりません。
ちなみに別のページ(indexなど)でSessionComponent::writeやSessionComponent::readを試したところ問題なく動きました。
なので、セッションの設定などに間違いがあるということでもなさそうです。
以下に問題のあるコードを記載します。いったいどこが間違っているのでしょうか?
具体的な解決策をわかりやすくお願いします。
追記1:var_dumpで確認したところ、$this->Session->write('conditions', $conditions);がfalseになっていました。なぜ、falseになってしまうのかがわかりません。
追記2:if($this->request->is('post') && $this->request->data != ""){}内の一行目に$this->Session->writeを使うと、値でも配列でも変数でも書き込めてvar_dumpでtrueとなりました。
$areas_id = $this->request->data['area'];以降にセッションを書き込むとどのような値でもfalseとなってしまいます。
ただの変数代入の行の前後でなぜ、このようなことが起きてしまうのでしょうか?
引き続き、よろしくお願いします。
<?php
// app/Controller/SitesController.php
App::uses('AppController', 'Controller');
class SitesController extends AppController {
public $uses = array('Spot', 'Area', 'Category', 'SpotsStatus', 'SubCategory', 'Plan', 'PlansSpot');
public $components = array('Paginator', 'Flash', 'Session');
public $paginate = array(
'Spot' => array( //モデルごとにページネーションの設定を記入
'limit' =>10, //1ページ表示できるデータ数の設定
'order' => array('id' => 'asc'), //データを降順に並べる
)
);
public function search($page = null, $sort = null, $direction = null) {
$this->Paginator->settings = $this->paginate;
$this->Spot->recursive = 0;
$this->set('area', $this->Area->find('list', array('fields' => array('id', 'name'))));
if($this->request->is('post') && $this->request->data != ""){
//Formの値を取得
$areas_id = $this->request->data['area'];
//session用
$search['areas_id'] = $areas_id;
$conditions['areas_id'] = $areas_id;
//検索条件をセッションに保存
if($this->Session->check('conditions')){
$this->Session->delete('conditions'); //古いのは削除
};
if($this->Session->check('search')){
$this->Session->delete('search'); //古いのは削除
};
$this->Session->write('conditions', $conditions);
$this->Session->write('search', $search);
$this->Paginator->settings['Spot']['conditions'] = array(
'areas_id' => $conditions['areas_id'],
);
$this->set('results', $this->Paginator->paginate('Spot'));
$this->set('data', $this->Session->read('conditions'));
}else{
if($this->Session->check('conditions')){
//パラメータがなければ新しい検索のため削除
if(empty($this->params['named']['page']) && empty($this->params['named']['sort']) && empty($this->params['named']['direction'])){
$this->Session->delete('conditions');
$this->Session->delete('search');
}else{
$conditions = $this->Session->read('conditions');
$search = $this->Session->read('search');
$this->Paginator->settings['Spot']['conditions'] = array(
'areas_id' => $conditions['areas_id'],
);
$this->set('results', $this->Paginator->paginate('Spot'));
$this->set('search', $search);
}
}
};
}
// app/View/Sites/search.ctp
<?php echo $this->Form->create('Sites', array('type'=>'post','action'=>'./search'));
echo $this->form->input('area' ,array(
'type'=>'select' ,
'multiple' =>'checkbox',
'options' => $area,
//'selected' => $selected,
'label' => false, //ここのラベルは'area'の部分をこのチェックボックスのタイトルにしないためのもの
'hiddenField' => false,
'div' => false
)
);
echo $this->Form->end('Finish'); ?>
<?php foreach ($results as $result): ?>
<?php
echo $this->Html->link(
$result['Spot']['name'],
array('controller' => 'sites', 'action' => 'view', $result['Spot']['id'])
);
?>
<?php echo $result['Areas']['name']; ?>
<?php endforeach; ?>
<div class="paging">
<?php
echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
echo $this->Paginator->numbers(array('separator' => ''));
echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
?>
</div>
<?php
echo $this->Html->link(
'トップ',
array('controller' => 'sites', 'action' => 'index')
);
?>
<?php debug($data); //確認用 使わなくなれば消してよい ?>
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
check解決した方法
0
$areas_id = $this->request->data['area'];
//session用
$search['areas_id'] = $areas_id;
$conditions['areas_id'] = $areas_id;
この部分なのですが、本来のコードは同種のcategory_idとsubcategory_idも並列でそれぞれ書いていました。
それで、area_idについてはサンプルの値をMySQLに入れておきましたが、残りの二つはまだ入れてありませんでした。
それが原因だったらしく、category_idとsubcategory_idについての行をコメントアウトにしたところ、問題なく動作しました。
一見関係ない場所でも内部的に動作不良を起こす場合があるようなので、後々必要になるからと書いておくなどの行為にも注意が必要だということがわかりました。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
この行の
if($this->request->is('post') && $this->request->data != ""){
//略
}
これ
&& $this->request->data != ""
は何を意図しているんでしょうか?
これのせいでこのブロックには絶対入らないと思います。
とりあえず、var_dump()と各所に組み込んで、どこをどう通っているかをちゃんと確認しながら作ったほうが良いですよ?
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.35%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる