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

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

ただいまの
回答率

90.23%

CakePHPでコントローラーから別のコントローラーのアクションを表示させたい

解決済

回答 2

投稿 編集

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

imohead

score 13

CakePHPで顧客情報を管理するシステムを作成しています。
顧客情報を入力するのは、ClientsController.phpで行っています。
顧客は、企業に属するので企業情報を入れるClientCompanies.phpという別のコントローラーで企業情報を入力する仕組みにしました。

Ajaxで顧客情報のaddアクション内からClientsCompaniesコントローラー内のaddアクションを呼び出したいのですが、画面は呼び出されますが、変数が未定義(undefined Companies)というエラーがでます。
変数を$this->set~してから、renderすれば良いと思いますが、ClientsCompaniesのaddアクション内に記載した記述をコピーするのはスマートではないと思いましたので、何か方法があればご教示ください。

以下ソースコードです。(企業情報の検索や、ページネーション、モデルに記載した関数などがオリジナルのコードに含まれており、混乱させてしまうのでコードは省略しています)
顧客情報 ClientsController.php

class ClientsController extends AppController {
 public function add(){
  if ($this->RequestHandler->isAjax()) {
   $this->render('/ClientCompanies/add',"ajax");
  }
 }

顧客情報 入力フォーム add.ctp

<?php
echo $this->Form->create();
echo $this->Js->submit('企業情報を入力', array(
    'success'=>$this->Js->get('#sending')->effect('fadeOut'),
    'update'=>'#success'
));
echo $this->Form->end();
?>
<div id="success"></div>
<?php echo $this->Js->writeBuffer(); ?>

企業情報 ClientCompaniesController.php

class ClientCompaniesController extends AppController {
 public function add(){
  $Companies = $this->ClientCompany->find('list');
  $this->set('Companies ', $Companies);
 }
}

企業情報 入力フォーム add.ctp

<?php foreach($Companies as $comp):?>
 <p><?php echo $comp;?></p>
<?php endforeach;?>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+1

コンポーネントを利用してみてはどうでしょうか。
アプリケーションフォルダ/Controller/Component/ 下に作成するクラスで、コントローラー間の共通処理を書くために使います。
例えば CompanyComponent に更新処理を書き、ClientsController::add() と ClientCompanies::add() の両方から呼び出すという感じです。

もしコントローラ間でコピーアンドペーストしたい箇所が あった場合、その機能を含むコンポーネントの作成を検討しましょう。

引用: http://book.cakephp.org/2.0/ja/controllers/components.html

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/03/20 15:53

    確かに一覧のリストを取得して表示などはそちらにまとめてしまえば横断的にできそうですね。
    ありがとうございます。

    試してみます

    キャンセル

0

少々わかりにくい内容になっている部分があります。いちど整理しましょう。

/ClientCompanies/add.ctp ※ここでユーザがSUBMITする
↓ AJAX
ClientsController add()

という顧客情報をAJAXで更新するものが既に存在していて、
この中で顧客情報だけではなく、企業情報も更新したいので、
ClientsController add() の中から、ClientCompaniesController add()を呼び出したいという意図であってますか?

ご提示してもらったソースコードは必要な処理が削られすぎていて意図が読み取りにくいので、
詳細な処理まで記載されたコードを掲載することをおすすめします!

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/03/01 16:28

    ありがとうございます。
    流れについては、正確には逆です。
    /ClientCompanies/add.ctp
    ↑ AJAX
    ClientsController add() ※ここでユーザがSUBMITする
    顧客情報だけではなく、企業情報も更新したいという意図はご理解頂いている通りです。

    処理前のソースコードの掲載についてですが、
    企業情報の検索や、ページネーション、モデルに記載した関数など、余計混乱させてしまうコードがあるので、上記の流れでお助け頂けると幸いです!

    キャンセル

  • 2016/03/01 16:50 編集

    共有してもらっているソースを見る限りでは

    /ClientCompanies/add.ctp ※ここでユーザがSUBMITする
    ↓AJAXリクエスト
    ClientsController add()
    で合ってると思います。

    そして、おそらく仰りたいのはレスポンスの話で、このadd()が返却する内容は、
    /ClientCompanies/add.ctp内の div#success に表示される内容になるわけですね。

    ここからは設計の話なんですが、

    案1
    「Client」を更新するコントローラーと「ClientCompanies」を更新するコントローラーという切り口で作成されているようですので、意味合い的にはJSから2個叩けば良いのではないかなと思ったりもします。

    案2
    しかしながら、そこは1回で済ませたいというのであれば、「Client」「ClientCompanies」とコントローラ分割している意味もとくにないので(結局、Clientリクエスト時にClientCompaniesを更新しようとしているので)、それならば、両方を更新するアクションとして記述するのが適切ではないかなと思います。

    案3
    そして、個人的には一番おすすめではありませんが、どうしても別アクションを呼び出したいのであれば、Client更新用のアクションとClientCompanies更新用のアクションを用意して、setActionで呼び出すなどはいかがでしょう。
    もちろん必要なハンドリングはあるでしょうが、イメージとしては下記のような。
    ただし、こうまでする必要性が全くない気がします。

    // AJAXで呼び出すアクション
    public function index(){
    $this->setAction("client");
    $this->setAction("companies");
    }
    // client更新用アクション
    public function client(){
    // 更新処理
    }
    // clientCompanies更新用アクション
    public function companies(){
    // 更新処理
    }

    ※場合にも寄りますが、このケースであれば、私は案2の形で作ると思います。

    キャンセル

  • 2016/03/20 15:55

    ありがとうございます。

    もともとは連携する予定はなかったのですが、やはり設計から見直した方が良さそうなんですね。

    コンポーネントを使うご助言を他の方からもいただいたので、試してみます。

    キャンセル

  • 2016/03/22 15:21

    コンポーネントは書き方の問題なので、実処理の構成としては、同時に両方を処理するコントローラにするという意味で案2の構成になりますね。検討を祈ります。

    返信ありがとうございました。

    キャンセル

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

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