- 更新日: 2016年3月12日
- PHP & CakePHP
CakePHPでDB関連テーブルのレコード・データを取得
CakePHP 3 の開発で、データベースの関連テーブル(アソシエーション)のレコード・データを取得する方法です。クエリーを作成する時に、明示的に contain を使って、データを取得する関連テーブルを指定する必要があります。
— 環境 —
PHP 5.5.19
CakePHP 3.1.1
以降の説明は、User has many Posts / Post belongs to User となっているアソシエーション関係での例です。
Posts に関連する Users のデータを取得する
Posts 一覧に関連する Users を同時に引っ張ってくる例です。
src/Controller/HomeController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace App\Controller; use Cake\ORM\TableRegistry; class HomeController extends AppController { public function index() { $posts_table = TableRegistry::get('Posts'); $posts = $posts_table ->find() ->contain(['Users']) ->order(['Posts.created' => 'DESC']); $this->set('posts', $posts); } } |
上記のように contain に Users を指定してクエリを作成すると、Posts テーブルに関連する Users のデータを取得できます。なお contain を使うと、Sql Log を確認したところ、INNER JOIN による SQL が発行されることを確認しました。
1 2 3 |
SELECT ... FROM posts INNER JOIN users ON users.id = posts.user_id |
また、order 句の指定では、created カラムが Posts テーブルにも Users テーブルにも存在するので、’Posts.created’ とソートに指定したいテーブル.カラム名を明示する必要がある。
ビューでは以下のように、$post->user で投稿ユーザーにアクセスできます。
src/Template/Home/index.ctp
1 2 3 4 5 |
<?php foreach ($posts as $post): ?> <p><?= $post->user->name; ?></p> <p><?= $post->title; ?></p> <p><?= $post->content; ?></p> <?php endforeach; ?> |
User に関連する Posts のデータを取得する
今度は逆に特定の User に関連する Posts のレコードを同時に引っ張ってくる例です。User が投稿した Posts を取得します。
src/Controller/UsersController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace App\Controller; use App\Controller\AppController; class UsersController extends AppController { public function view($id = null) { $user = $this->Users->get($id, [ 'contain' => ['Posts'] ]); $this->set('user', $user); $this->set('_serialize', ['user']); } } |
contain に Posts を指定することで、User に関連する Posts を取得できます。
Sql Log を確認したところ、以下の SQL が発行されていました。
1 2 3 4 |
SELECT ... FROM users WHERE users.id = 5 LIMIT 1 SELECT ... FROM posts WHERE posts.user_id in (5) |
ビューでは以下のように、$user->posts とすれば、ユーザーが投稿したポスト一覧にアクセスできます。
src/Template/Users/view.ctp
1 2 3 4 5 6 |
<p><?= $user->name; ?></p> <?php foreach ($user->posts as $post): ?> <p><?= $post->title; ?></p> <p><?= $post->content; ?></p> <?php endforeach; ?> |
以上、CakePHP 3 で contain を使っての関連テーブルのデータを取得する方法でした。
- PHP & CakePHP の関連記事
- PHP+MySQLでNo such file or directoryエラー
- bin/cakeコマンドでintlエラーが出る場合の対処(CakePHP)
- CakePHPアプリケーションをCapistranoでデプロイ
- Integrity constraint violation:Column ‘created’ in order clause is ambiguousエラー/CakePHP
- CakePHPでカラム属性に別名/エイリアスを付ける仮想フィールド
- CakePHPで日付選択フォームのカスタマイズ
- CakePHP3で現在のコントローラー名・アクション名を取得
- PHPインストールでconfigure: error: freetype.h not foundエラー
- CakePHPでログイン後に元のページにリダイレクトさせる
- CakePHPで全てのモデル/テーブル名一覧を取得
Leave Your Message!