CakePHPのアソシエーションの重要性について考える

今回はCakePHPのアソシエーションの重要性というか便利さについて実際にコードを比較しながら知ってもらいたいと思います。
以前、データベースのアソシエーションの設定を全く行わずにコードを書いていたのですが、ちゃんとアソシエーションの設定を行ったらこんなコードが短くてわかりやすく済むのか!と感動しました。

最初にアソシエーションについてすごく簡単に説明します。
データベースのテーブル間の多くはリレーショナル型という設計方法を採用しています。リレーショナル・データベースに関してはここがわかりやすくまとまっていますので読んでみてください。
そしてCakePHPにおいて、データベースの繋がりをアソシエーションという機能を用いて定義するのです。

それでは本題に入ります。Cakeのバージョンは2.x系です。データベースに関しては以下のとおりと仮定します。
【Blog(ブログ記事)】
・blog_id:integer(ブログID-主キー)
・title:varchar(タイトル)
・body:text(内容)

【Comment(ブログに関するコメント)】
・comment_id:integer(コメントID-主キー)
・blog_id:integer(ブログID-外部キー)
・body:text(内容)

今回はブログの記事の画面(app/View/Blogs/view.ctp)に投稿されたコメントを表示する方法をやってみたいと思います。

まず初めに、アソシエーションの設定を行わなかった場合を見てみましょう
app/Controller/BlogsController.php

 public function view($id = null) {
  $this->set('blog', $this->Blog->read(null, $id)); //blog_id読み込み
  App::uses('Comment', 'Model'); //クラスのローディング
  $this->Comment = new Comment(); //Commentモデルの読み込み
  $params = array(
    'conditions' => array('blog_id' => $id) //ブログIDを指定
  );
  $this->set('comments', $this->Comment->find('all', $params)); //ブログIDに沿ったコメント取得
}

app/View/Blogs/view.ctp

<ul>
  <?php foreach($comments as $comment) : ?>
    <li><?php echo h($comment['Comment']['body']); ?></li>
  <?php endforeach; ?>
<ul>

このようにしてコメント表示までを行います。

次にアソシエーションの設定を行った場合を見てみます。
app/Model/Blog.php

<?php
class Blog extends AppModel {
  public $hasMany = 'Comment'; //コメントをたくさん持つことを定義
}

app/Model/Comment.php

<?php
class Comment extends AppModel {
  public $belongsTo = 'Blog'; //ブログに属することを定義
}

app/Controller/BlogsController.php

public function view($id = null) {
  $this->set('blog', $this->Blog->read(null, $id)); //blog_id読み込み
}

app/View/Blogs/view.ctp

<ul>
  <?php foreach($blog['Comment'] as $comment) : ?>
    <li><?php echo h($comment['body']); ?></li>
  <?php endforeach; ?>
<ul>

アソシエーションの設定を行うのと行わないのではコントローラーのコード量にかなりの差が出ることがわかります。
また、コードの保守性も確実に高まります。
データベースの主キーや外部キーが正しい命名規則で定義されていれば、Cake側が勝手に繋げてあれこれしてくれるみたいです。便利ですね!

なので、Webアプリケーションを開発するときは初めにデータベース設計をきちんと行いアソシエーションの設定をしっかり行いましょう。

お見積もりフォーム