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

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

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

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

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

Q&A

解決済

1回答

1554閲覧

cake2のcontainerbleビヘイビアを使用してもマッチしないものまで取得してしまう

y.sudo

総合スコア19

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

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

0グッド

0クリップ

投稿2017/01/17 13:49

編集2017/01/18 01:03

お世話になります。

CakePHP2において、2つのテーブル、orderとdetailがあり order:detail = 1:N (hasMany)となっております。

findでの検索条件で、Containableビヘイビアを使用してdetail側の値を指定して検索をかけたのですが、どうしてもdetailが空のorderまで取得してしまい困っております。

cakeのマニュアルですと、これでアンマッチの方は出力されない感じなのですが、実際はそうでもないのでしょうか。(最終的な出力結果が記載されていなかったので、この結果が正なのかが判断できませんでした)

detail条件にマッチしているorderのみ取得したいと思っております。
(下記結果の1次元目の0番のみ取得したい)

以下詳細です。
●テーブル
[orders]

idname
1注文1
2注文2

[details]

idorder_idproduct
11商品1
21商品2
31商品3
42商品1
52商品2

●ソース(controller内)

$this->Order->Behaviors->load('Containable'); $list = $this->Order(find("all", array( 'contain' => array( 'Detail' => array( 'conditions' => array( 'Detail.order_id =' => 1, ), ), ));

●結果($listダンプ)

Array ( [0] => Array ( [Order] => Array ( [id] => 1 [name] => 注文1 ) [Detail] => Array ( [0] => Array ( [id] => 1 [order_id] => 1 [product] => 商品1 ) [1] => Array ( [id] => 1 [order_id] => 1 [product] => 商品2 ) [2] => Array ( [id] => 1 [order_id] => 1 [product] => 商品3 ) ) ) [1] => Array ( [Order] => Array ( [id] => 2 [name] => 注文2 ) [Detail] => Array ( ) )

見づらい箇所あると思いますが、よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

hasManyの場合、一つのfindでも、内部的にはorderとdetailを取得するSQLは別になっており、detailのconditionsはdetailを取得するSQLでのみ使われるため、orderはdetailがないものも取得されてしまいます。
※debug_kitのSQLを見るとよくわかると思います。

なので、hasManyなものをContainableを使ってフィルタすることはできません。joinsでdetailをinner joinsして、detail.idがnullではないものを探すとかしないとできないと思います。
なお、inner joinsすることで、orderの件数がdetail分だけ重複してしまうので、group byかdistinctで重複を排除する必要があるかもしれません。

以下、参考になりそうなもの

なお、Cakephp3ではmatching()という機能が追加されており、Containableを使ったフィルタができるようになっています。

投稿2017/01/17 20:56

popobot

総合スコア6586

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

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

y.sudo

2017/01/18 01:00

いつもご丁寧にありがとうございます。 (Cakeのバージョンを記載するのを失念しておりましたが、ご推察いただき感謝いたします) CakePHP2ではフィルタリングできないのですね。。 マニュアル上だといかにもできそうな記述でしたので残念です。 紹介いただいたURL、片方は拝見済で、確かにhasManyはアソシエーションとの相性が悪いと感じました。 joinsは試していたのですが、どうも取得した配列が思うような形にならず、断念しておりました。。 あまりやりたくはないですが、とりあえずこのまま取得し、detailが空のものを後から排除ループで排除しようと思いましたが、pagenateで取得している為、難がありそうです。 joinsで再度考えていきたいと思います。
popobot

2017/01/18 01:04

ページネートで使うなら後から消すだと件数などがおかしくなりそうなので、joinするのが普通だと思いました。
y.sudo

2017/01/18 01:43 編集

仰る通り、件数がおかしくなる為、joinしかなさそうですが、joinで取得した際、同じorderも別行となってしまうのと、さらにdetail側でbelongsToで繋がっているものも取得されない為、なんとかcontainableで収めたかったのですが。。 もう少し考えたいと思います!ありがとうございます!
popobot

2017/01/18 01:48

そうですね。なのでorder.idでdistinctして重複を排除すればいいと思います。 なおjoinはあくまでdetailがあるかないかを判断するために使うだけにして、detailのデータを取得するのにはcontainableを使った方がいいです。detailを2回使うことになりますけど、目的が違うので仕方ないです。
y.sudo

2017/01/18 02:23

なるほど。。実は先にdetail側でdistinctしたorder_idを取得しておいて、その後別でfindする方法は試しておりました。やはりdetailを2回使うのは仕方がないことなのですね。 なかなか方法が確定できませんでしたが、これで確定できそうです。 非常に助かりました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問