🍰

フラッシュメッセージが表示されないときは手動レンダリングで

2020/09/20に公開

CakePHPのフラッシュメッセージは、Controllerクラス内で$this->Session->setFlash('Message')することで処理の成否などを出力できる便利な機能ですが、クラスの規模が拡大してメソッドの分割などを始めると正常に表示されなくなります。ハマったので解決方法を記しておきます。

##問題が起きる状況

public function add() {
    if ($this->request->is('post')) {
        if ($this->Post->save($this->request->data)) {
            $this->Session->setFlash('Success!');
            $this->redirect(array('action'=>'index'));
        } else {
            $this->Session->setFlash('Failed!');
        }
    }
}

このようにadd()のみで完結するならば問題はありません。このソースが肥大化して、もし以下のようになったら問題が発生します。

public function add() {

    /* 何らかの処理 */

    if ($this->request->is('post')) {
        $this->_otherMethod();
    }
}

protected function _otherMethod() {

    /* 何らかの処理 */

    if ($this->Post->save($this->request->data)) {
        $this->Session->setFlash('Success!');
        $this->redirect(array('action'=>'index'));
    } else {
        $this->Session->setFlash('Failed!');
    }
}

この状態では、add()の処理から_otherMethod()の処理に移るときに先にレンダリングを始めてしまいます。
つまりsetFlash()するより前にdefault.ctpが呼び出されてしまうのでフラッシュメッセージは出力されません。

##解決法

_otherMethod()の処理後にレンダリングされるのが望ましいため、オートレンダリングをオフにする必要があります。

public function add() {
    $this->autoRender = false; // この行を追加

    /* 何らかの処理 */

    if ($this->request->is('post')) {
        $this->_otherMethod();
    }
}

protected function _otherMethod() {

    /* 何らかの処理 */

    if ($this->Post->save($this->request->data)) {
        $this->Session->setFlash('Success!');
        $this->autoRender = true; // この行を追加
        $this->redirect(array('action'=>'index'));
    } else {
        $this->Session->setFlash('Failed!');
        $this->autoRender = true; // この行を追加
    }
}

処理の前後で$this->autoRenderを操作すれば、望ましい処理順と出力になります。

Discussion