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

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

新規登録して質問してみよう
ただいま回答率
85.48%
CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

1回答

6880閲覧

CakePHPのJOINしたpaginateでのJOIN側の検索ができない。

asibarcom

総合スコア7

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

0クリップ

投稿2015/12/11 13:24

表題の件で、いろいろな文言でググっても解決策がわからず・・・
助けてください。

AAAテーブルにLEFT JOINにてBBBテーブルを結合し、BBB内を検索したいのですが、
現状では、AAAしか検索できません。
DebugKitでSQLログを見ると、AAAテーブルをLIMIT検索し、AAA.IDをもとに、BBBテーブルをWHERE INにて検索してるみたいです。それなので、BBB側を検索するとそもそもそんなカラムはないとエラーになります。
なので、$paginateのコメントアウトしてる'join'を追加すると・・・
検索はできるのですが。paginateのカウント処理でLEFT JOINが同じBBBを2回行いSQLエラーになります。

モデル側

php

1class AmznGiftCode extends AppModel { 2 public $hasOne = array('AmznGiftCodeUse'); 3}

コントローラー

php

1class xxxxxController extends AppController { 2 3 var $uses = array('AAA',"BBB"); 4 5 //読み込むコンポーネントの指定 6 public $components = array('Paginator'); 7 8 public $paginate = array( 9 'limit' => 50, 10 'maxLimit' => 1000, 11 'order' => array( 12 'AmznGiftCode.id' => 'asc' 13 ), 14 'group'=>"AmznGiftCode.id", 15 'paramType' => 'querystring' 16 // ,'joins' => array( 17 // array( 18 // 'type' => 'LEFT', 19 // 'table' => 'bb_bb_bb', 20 // 'alias' => 'BBB', 21 // 'conditions' => 'BBB.aaa_id = AAA.id' 22 // ) 23 // ) 24 ); 25〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 26public function index(){ 27 $this->AAA->unbindModel(array('hasOne' => array('BBB'))); 28 $this->AAA->bindModel(array('hasMany' => array('BBB'=> array('order' => 'id DESC'))),true); 29〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 30 31 $conditions = array(); 32 if(isset($this->params['url']['text']) && !empty($this->params['url']['text'])){ 33 //Formの値を取得 34 $text = $this->params['url']['text']; 35 //検索文字を空白(全角又は半角)で区切って配列$keywordsに代入 36 $keywords = preg_split("/ |\s/",$text); 37 //配列$keywordsの数だけ繰り返して検索条件を$conditionsに代入 38 foreach($keywords as $keyword){ 39**AAA.claim_codeは検索できるけど、BBB.emailが検索できない** 40 $conditions[] = "`AAA`.`claim_code` like '%$keyword%' OR `BBB`.`email` like '%$keyword%'"; 41 } 42 $search_condition['text'] = $text; 43 } 44 45 //ページングパラメーター設置 46 $this->Paginator->settings = $this->paginate; 47 48 $data = $this->Paginator->paginate('AAA',$conditions); 49 $this->set('AAAView', $data);

この情報だけで分かりますか?必要情報あれ追記いたします。

お分かりになる方よろしくお願いします。
お力添えをお願いいたします。

ーー 環境情報 ーー
CAKE_VERSION:2.7.5
Apache:2.4.16
PHP:5.5.28
MySQL:5.6.26
ーーーーーーーーーー

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

プラグインを入れる等、手法は様々かと思いますが、
コメントアウトされているjoins部分のコードを生かした場合の回答です。

paginateのカウント処理でLEFT JOINが同じBBBを2回行いSQLエラーになります。

とありますが、bindModelのコードをそのまま残していませんか?

PHP

1$this->AAA->bindModel(array('hasMany' => array('BBB'=> array('order' => 'id DESC'))),true);

$paginateにて手動で結合を指定している為、必要ありません。


  1. joins部分のコメントアウトを元に戻す
  2. bindModel部分をコメントアウト

私の環境ではこの方法で正常に動作しましたが、質問のコードだけでは分からない部分は補完しましたので、元のコードとは異なったコードです。
ひとまずこれで正常に動作するか確認していただけますでしょうか?

投稿2015/12/12 05:54

編集2015/12/12 05:57
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asibarcom

2015/12/14 04:43

返事が遅くなり申し訳ありません。 1.joins部分のコメントアウトを元に戻す 2.bindModel部分をコメントアウト にて対応してみましたが・・・ 同じテーブルのJOINが2つになりエラーになりました・・・ Error: SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'BBB' SELECT COUNT(*) AS `count` FROM `aaa` AS `AAA` LEFT JOIN `bbb` AS `BBB` ON (`BBB`.`aaa_id` = `AAA`.`id`) LEFT JOIN `bbb` AS `BBB` ON (`BBB`.`aaa_id` = `AAA`.`id`) WHERE 1 = 1 GROUP BY `AAA`.`id` さらに必要な情報等ございますか?
退会済みユーザー

退会済みユーザー

2015/12/14 05:11

AAAテーブルに対してBBBテーブルが2度結合されています。 2度の内の一つは'joins'で指定したもの、もう一つは$hasOneアソシエーションではないかと思います。 今回の回答で必要な結合は'joins'のものだけです。 なのでAAAとBBBのアソシエーションを見直すと良いかもしれません。 ぱっと思いつくところではこの3つ。 ・unbindModelも一緒にコメントアウトしていないか? ・recursiveに-1を設定してみる。 ・Continableビヘイビアを導入し、'contain' => array()を指定してみる。 必要な情報と言えば、AmznGiftCodeはAAA、AmznGiftCodeUseはBBBとそれぞれ別名を付けているという事で良いですかね?
退会済みユーザー

退会済みユーザー

2015/12/14 06:25 編集

再度環境を組み直して検証してみました。 paginateの呼び出し前にAAAモデルのrecursiveを-1にしてみてください。 $this->AAA->recursive = -1; $data = $this->Paginator->paginate('AAA',$conditions); ただしこの場合$dataにBBBのデータは入ってきませんので、BBBのデータが欲しい場合はPaginatorの設定時にfieldsにて必要なカラムを指定してください。 public $paginate = array( 'limit' => 50, 'maxLimit' => 1000, 'order' => array( 'AmznGiftCode.id' => 'asc' ), 'group'=>"AmznGiftCode.id", 'paramType' => 'querystring', 'joins' => array( array( 'type' => 'LEFT', 'table' => 'bb_bb_bb', 'alias' => 'BBB', 'conditions' => 'BBB.aaa_id = AAA.id' ) ), // ここで取得するカラムを指定 'fields' => array('AAA.id AS a_id', 'BBB.id AS b_id', 'BBB.email AS email') ); これで動くとイイナー
asibarcom

2015/12/22 06:05

すごい遅くなってすみません。 ありがとうざいます。 d_s_1さんと同じようにしたらできました。
退会済みユーザー

退会済みユーザー

2015/12/22 06:21

動いてよかったデス。 recursiveやbindModelの設定は凄く煩わしいもので、これらを頻繁に変更するような処理はよくバグが入り込んだりします。 出来る限りContinableビヘイビアを使っていくことをオススメします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問