CakePHP3のクエリービルダーで詰まったところ
開発環境は、Windows 10 Pro(64bit) + PHP 7.2.12 + CakePHP 3.6.13。
SQL文を直接書く時は簡単なんですけど、それをクエリービルダーをやる場合に、詰まってしまったポイントを書いておきます。
■クエリービルダーでselect句を使う際のカラム名について
クエリービルダーでitemsテーブルから情報を取得する際に、
<?php $this->Items->find() ?>
と書くと、生成されるSQL文では、select句にて、各カラムの名前を、『頭文字が大文字のテーブル名__カラム名』というエイリアスにas句を使って自動的に変更しています。
例えば、itemsテーブルに、priceというカラムがあれば、『Items__price』という名前に自動的に変更しています。
そして、テンプレート側で取得結果を表示する場合は、
1.カラム名が頭文字が大文字のテーブル名__カラム名
(例: Items__price
2.カラム名
(例: price
のどちらかに、as句で変更していると、foreachなどでレコード1つ分を取得した際に、$item->カラム名(例えば、$item->price)のやり方で問題なく読み込んで表示しますが、それ以外の場合は、その名称で、指定しないといけませんので、ちょっと面倒。
select文でのカラム名の変更の方法は、itemsテーブルにて、Items__priceカラムをpriceカラムに変更したければ、
<?php $this->Items->find()->select(['price' => 'Items__price']); ?>
とするだけで良いです。
■タイトル、記事内容、タグの中に特定のキーワードがあれば、結果として返す場合のクエリービルダーの例
SQL関数であるconcatでタイトルと記事内容とタグを結合したものを、LIKE句を使って、検索することにします。
<?php $query = $this->Articles->find(); $concat = $query->func()->concat(['title' => 'identifier', 'article' => 'identifier','article_tag' => 'identifier']); $subquery = $query->select(['combine_string' => $concat])->select($this->Articles); $q = $this->Articles->select(['id' => 'Articles__id', 'title' => 'Articles__title', 'article' => 'Articles__article', 'article_tag' => 'Articles__article_tag'])->from(["result" => $subquery])->where(['AND' => [['result.combine_string LIKE' => '%キーワード1%'], ['result.combine_string LIKE' => '%キーワード2%']])->order(['result.id' => 'DESC']); $this->set('result', $this->paginate($q)); ?>
参考リンク
CONCAT:文字列を結合する
CakePHP3.x ORMでFrom句に仮想テーブルを追加する方法 - Qiita
クエリービルダー - 3.7