タスクにメモをつけられるようにしよう

各タスクに対してメモもつけられたら便利ですよね。
tasksテーブルでメモを管理しても良いのですが、今回はnotesというテーブルを新しく作成し、アソシエーションによって2つのモデルを関連付けましょう。
モデルは基本的に独立して動きますが、アソシエーションを効かせることで、Taskモデルから値を取得するとき、一緒にNoteモデルからも値を引っ張ってくるようになります。

notesテーブルの作成
下記のSQL文により、notesテーブルを作成しましょう。

CREATE TABLE `notes` ( 
`id` INT NOT NULL AUTO_INCREMENT, 
`task_id` INT NOT NULL, 
`body` TINYTEXT NOT NULL, 
`created` DATETIME NOT NULL, 
`modified` DATETIME NOT NULL, 
PRIMARY KEY (`id`)) ;

Noteモデルの作成
次にnotesテーブルに対応するNote.phpを作成します。
$belongsToがアソシエーションに必要なプロパティですが、これは後ほど説明します。

<?php
// app/Model/Note.php
class Note extends AppModel {
public $belongsTo = array('Task');
}

Notesコントローラーの作成
NotesController.phpです。
面倒なので、$scaffoldを使ってしまいましょう。

<?php
// app/Controller/NotesController.php
class NotesController extends AppController {
public $scaffold;
}

ここまで実装した上で、http://192.168.33.10/cakephp-tasks/Notes/createにアクセスしてみると、$scaffoldによって生成されたページが表示されます。
Taskという項目で、すでに登録したタスクが選択できるのが分かるでしょうか?
これはアソシエーションにより、NoteモデルがTaskモデルに紐付いていると定義されたからです。

ただし、このままだとNoteモデルからTaskモデルへの片思いなので、Taskの方も修正します。

Taskモデルの修正

<?php// app/Model/Task.php
class Task extends AppModel {
public $hasMany = array('Note');
// ここから下は前項のバリデーションなので省略
}

ここで出てきた$hasManyと先程の$belongsToがアソシエーションのキモです。
$hasManyと$belongsToをざっくり説明すると以下のようになります。

$hasMany => このモデルはいくつかのモデルを従えている(上位モデル)
$belongsTo => このモデルは上位モデルの下についている(下位モデル)
Task.phpは$hasMany、Note.phpは$belongsToでお互いを指定しているので、

上位モデル => Task
下位モデル => Note
となります。

つまり、どういう動きするんだってばよ?
ということで、続いてビューも修正していきます。

一覧ページの修正

<!-- app/View/Tasks/index.ctp --><!-- 省略 -->
<table> 
<tr> 
<th>ID</th> 
<th>名前</th> 
<th>期限日</th> 
<th>作成日</th> 
<th>操作</th> 
</tr> <?php foreach($tasks_data as $row): ?> 
<tr> 
<td><?php echo $this->Html->link($row['Task']['id'], '/Tasks/view/' . $row['Task']['id']); ?></td> 
<td><?php echo h($row['Task']['name']); ?><br /> 
<ul> <?php foreach($row['Note'] as $note): ?> 
<!-- Noteモデルのデータを表示 --> 
<li><?php echo h($note['body']); ?></li> 
<?php endforeach; ?> 
</ul> 
</td> 
<td><?php echo h($row['Task']['due_date']); ?></td> 
<td><?php echo h($row['Task']['created']); ?></td> 
<td><?php echo $this->Html->link('このタスクを完了する', '/Tasks/done/' . $row['Task']['id']); ?></td> 
</tr> 
<?php endforeach; ?>
</table>
<!-- 省略 -->

コントローラーは変えておりませんが、アソシエーションを組むことで、Taskモデルから値を取得する際にNoteモデルからも値を取得してきます。
そのため、同じ$task_dataでありますが、tasksテーブルの値とnotesテーブルの値を含んでおります。
後は、トリガーにモデル名を指定してあげれば、そのモデルの値を引っ張ってきます。($row[‘Task’]、$row[‘Note’])

それではアクセスしてみてください。
え、何も変わらないって?
そうですね。まだnotesテーブルに何も値を入れていませんでした。

下記のアドレスにアクセスし、notesテーブルに新規登録しましょう。
http://192.168.33.10/cakephp-tasks/Notes/create
このとき、Taskの項目を選択すると、あなたがすでにtasksデータに登録した値が表示されます。
これもアソシエーションのおかげです。

それでは好きなタスクに好きなメモを残しましょう。
メモを登録したら、http://192.168.33.10/cakephp-tasks/Tasks/indexに戻りましょう。
メモが登録されていますね。

余談ですが、画面下部に出ているのが、このページにてモデルが実行した処理です。
ちゃんとtasksテーブルとnotesテーブルの両方から取得していることが分かります。

カテゴリー

アーカイブ

Close Bitnami banner
Bitnami