前回のでbooksテーブルと直接繋がっているテーブルは結合できましたが、更に連鎖した先のテーブルを結合することも出来ます。
とりあえず前回のテーブル群にレーベルテーブル追加。
CREATE TABLE `labels` ( `id` int(8) NOT NULL AUTO_INCREMENT, `publisher_id` int(8) NOT NULL, `name` varchar(32) NOT NULL, `comment` text NOT NULL, `created` datetime NOT NULL, `modified` datetime NOT NULL, PRIMARY KEY (`id`), KEY `publisher_id` (`publisher_id`), KEY `publisher_id_2` (`publisher_id`), CONSTRAINT `labels_ibfk_1` FOREIGN KEY (`publisher_id`) REFERENCES `publishers` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
どう考えてもbooks.label_id→labels.publisher_id→publishersが正しい流れですが所詮サンプルなので気にしない。
次はモデルを追加です。
Books→Publishersの関係はBookモデルに書いてありますので、次はPublishers→Labelsの関係を記述する必要があります。
ではPublishersモデルを作成しましょう。
app/models/publisher.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class Publisher extends AppModel {
//自分の名前
var $name = 'Publisher';
//publishers.idはlabels.publisher_idから外部キー
var $hasOne = array(
'Label' =>
array(
'className' => 'Label',
'foreignKey'=> 'publisher_id'
)
);
}
|
毎回全リレーションを呼び出しているとパフォーマンス的に大変なので、デフォルトでは1段階しか呼ばれないようになっています。
Booksを呼び出した場合はPublishersまでしか呼ばれないということです。
これを2段階まで呼び出すようにする必要がありますが、単にコントローラに一行追加すればOKです。
app/controllers/book_controller.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//Bookコントローラ
class BookController extends AppController{
//自分の名前
var $name = 'Book';
//Book/indexAction
public function index() {
//Bookモデルを2階層までキーを追う
$this->Book->recursive=2;
//Bookモデルを取得
$this->set('books', $this->Book->findAll(array('Book.id <>'=>'1')));
}
}
|
このように2段階目まで簡単に取得することができます。
SELECT (略) FROM `books` AS `Book`
LEFT JOIN `authors` AS `Author` ON (`Book`.`author_id` = `Author`.`id`)
LEFT JOIN `publishers` AS `Publisher` ON (`Book`.`publisher_id` = `Publisher`.`id`)
WHERE `Book`.`id` <> 1
前回LIMIT 1が取れない、みたいなことを言いましたが、単にfindが一件取得で、findAllが全件取得だっただけでした。
CakePHPの記事一覧
PR
トラックバック
トラックバックURL: