home
スポンサーリンク
2016-08-30

CakePHP 3のORM matchingメソッドで複数の条件を指定したい

CakePHP 3系にて、アソシエーションを利用する場合に便利なmatchingメソッド。

便利に活用させていただいていたのですが、利用していく上で、複数の条件を指定する場合において少し悩んだので、備忘録として。

使い方

まずは通常の使い方から。

matchingは、多対多(belongsToMany)の関係を持つ2つのテーブルにおいて、片一方のテーブルに紐づくデータによって、もう片一方のテーブルから取得するデータをフィルタリングするメソッドです。

例えば、ブログの記事情報を格納するPostsテーブルとブログのタグ情報を格納するTagsテーブルが存在する場合、この2つのテーブルは多対多の関係(ブログは複数のタグを持ち、タグは複数のブログに割り当てられる)となりますが、特定のタグを持つブログのみを絞り込んで取得したい場合などに、このmatchingメソッドの出番となります。

特定のタグを持つブログのみを絞り込んで取得したい場合は、以下のようなコードで取得できます。

上記のコードで、”CakePHP”というタグを持つPostsだけに絞り込まれるようになります。

複数の検索値のうち、少なくともどれか一つにマッチするデータを取得する

例えば、”CakePHP”と”PHP”というタグの、少なくともどちらか一方を持っているブログ記事を取得するには、以下のようにします。

検索条件を配列で保持し、IN句を用いることで比較的簡単に実装可能です。2つ以上の条件の場合においても、配列の要素数を増やすだけで動作します。

複数の検索値のうち、全てにマッチするデータを取得する

例えば、”CakePHP”と”PHP”というタグの、両方ともを持っているブログ記事を取得するには、以下のようにします。

検索条件を配列で保持し、IN句、GROUP BY句及びHAVING句を用いることで実装可能です。2つ以上の条件の場合においても、配列の要素数を増やすだけで動作します。

複数の関係における検索値をAND条件で取得したい

例えば、Postsと多対多の関係にあるテーブルがTagsとCategories(カテゴリー情報)の2つあり、その両方の検索結果にてAND条件で絞り込みたい場合、単にmatchingメソッドを2度実行するだけで実装可能です。

上記のコードでは、「タグに”CakePHP”もしくは”PHP”を持ち、なおかつカテゴリに”IT”もしくは”コンピュータ”を持つブログ記事」を取得します。

複数の関係における検索値をOR条件で取得したい

Postsと多対多の関係にあるテーブルがTagsとCategoriesの2つあり、その両方の検索結果にてOR条件で絞り込みたい場合、例えば「タグに”PHP”、もしくはカテゴリーに”IT”を持つブログ記事を取得する」などの条件をmatchingメソッドを用いて一度に実行するのは、いろいろ調べてみましたが不可能なようです。(可能である場合は是非教えていただきたい)

実装したい場合は、matchingメソッドを使わずにクエリビルダでSQLを生成していくか、サブクエリを用いて実行する必要があります。サブクエリを用いて実行する例を以下に示します。

サブクエリで該当のブログ記事のID一覧を取得し、そのIDを条件にOR条件で取得しなおすことで、複数の関係におけるmatchingメソッドのOR条件を実現しています。

参考サイト

コメントを残す

スポンサーリンク
スポンサーリンク
ツイートする
シェアする
オススメする
ブックマークする
購読する