Post hasMany Comment, Comment belongsTo Post
新しいエンティティとしてCommentモデルを作成
CakePHPのブログチュートリアルの続きとして、モデル部分を拡張していきます。
既存のPostモデルとUserモデルの連携については、データモデル入門で解説してみました。
本記事では、
- Commentモデルの追加とアソシエーションの設定
- Tagモデルの追加とアソシエーションの設定
上の2つについて書きます。
最初にCommentモデルを追加します。
UserとPostとCommentの関係
コメントは記事(Post)に属するエンティティなので、
Post > Comment
という関係になります。アソシエーション的には、
Post hasMany Comment
と表現できます。ブログチュートリアル全体で考えると
User > Post > Comment
というリレーションを構築することになります。
テーブルの定義
データベースにcommentsテーブルを定義します。
CREATE TABLE IF NOT EXISTS `comments` ( `id` int(10) unsigned NOT NULL, `body` text, `created` datetime DEFAULT NULL, `modified` datetime DEFAULT NULL, `user_id` int(11) DEFAULT NULL, `post_id` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `comments` (`id`, `body`, `created`, `modified`, `user_id`, `post_id`) VALUES (1, 'コメント1', '2014-12-01 20:11:58', NULL, 1, 1), (2, 'コメント2', '2014-12-01 20:11:58', NULL, 1, 1), (3, 'コメント3', '2014-12-01 20:11:58', NULL, 1, 4);
hasManyを設定
PostモデルにhasManyを追加します。
public $hasMany = 'Comment';
この設定によりPostに紐づくCommentを同時に取得することが可能になります。
debug($this->Post->findById(1));
返されるデータ構造は以下の通りです。
array( 'Post' => array( 'id' => '1', 'title' => 'タイトル', 'body' => 'これは、記事の本文です。', 'created' => '2014-12-01 20:11:58', 'modified' => null, 'user_id' => '1' ), 'User' => array( 'password' => '*****', 'id' => '1', 'username' => 'engineer', 'role' => 'admin', 'created' => '2014-12-01 17:56:01', 'modified' => '2014-12-01 17:56:01' ), 'Comment' => array( (int) 0 => array( 'id' => '1', 'body' => 'コメント1', 'created' => '2014-12-01 20:11:58', 'modified' => null, 'user_id' => '1', 'post_id' => '1' ), (int) 1 => array( 'id' => '2', 'body' => 'コメント2', 'created' => '2014-12-01 20:11:58', 'modified' => null, 'user_id' => '1', 'post_id' => '1' ) ) )
PostとCommentが1対多の関係で対応していることが確認できます。
a href=”http://dim5.net/cakephp/data-modeling.html”>データモデル入門でPostモデルにUserモデルとのbelongsToを設定した関係で、Postに対応するUserも同時に返されています。
CommentモデルにbelongsToを設定
Comment belongsTo Post
のアソシエーションを設定します。Commentモデルを作成した上で、belongsToを追加します。
class Comment extends AppModel { public $belongsTo = 'Post'; }
CommentモデルからPostモデルへbelongsToを設定することで、多対1のデータ構造を得ることが可能になります。
$data = $this->Comment->find('all', array( 'conditions'=>array( 'post_id' => '1' ) )); debug($data);