http://yuubiseiharukana.blog.shinobi.jp/Entry/158/の続き?
CakePHPの基本は、ひとつのコントローラにひとつのテーブルです。
つまり、その状態ではリレーショナルをまともに扱うことができません。
複数のテーブルを扱いたい場合、実現には幾つかの手段があります。
単純に結合で話が済む場合は、モデルを記述することで解決されます。
とりあえず結合を使うようなテーブルを作成。
CREATE TABLE `books` ( |
とりあえず適当に作っただけなので各テーブルにはあまり意味はありません。
各テーブルに何件か適当にデータを入れておきます。
モデルに、他のモデルとの関係を記述していきます。
モデルとして読み込もうとしているBooksモデルの記述は必要ですが、そこからリンクされているAuthorsモデルやBooks_supplementationsモデルはとりあえず記述する必要はありません。
app/models/book.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
class Book extends AppModel {
//自分の名前
var $name = 'Book';
//books.author_idはauthors.idに外部キー
//books.publisher_idはpublishers.idに外部キー
//books.idはbooks_supplementations.book_idから外部キー
//といった関係を記述しておくとfind等で自動的に結合する
var $belongsTo = array(
'Author' =>array(
'className' => 'Author',
'foreignKey'=> 'author_id'
)
,'Publisher' =>array(
'className' => 'Publisher',
'foreignKey'=> 'publisher_id'
)
);
var $hasMany = array(
'Books_supplementation' =>
array(
'className' => 'Books_supplementation',
'foreignKey'=> 'book_id'
)
);
}
|
記述がめんどくさいんですが、簡単に言うとhasは相手側テーブルから自分に対して外部キーが張ってある、belongsToは自分から相手側に外部キーが張ってあるということです。
Bookモデルの場合、authorsテーブルとpublishersテーブルに対して外部キーが張ってあり、books_supplementationsテーブルから外部キーを張られています。
その後コントローラ内で
$this->Book->find(array('Book.id <>'=>'2'));
などとすると、Bookモデル内の結合条件を勝手に読み取って勝手にJOINなんかを付け加えてSELECTしてきます。
結果のSQLはこんな感じに。
見事に表示できま…一件しか出てこない。
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` <> 2
LIMIT 1
CakePHPの記事一覧
2009/10/30追記
findは結果セットを1件だけ取得するメソッドで、全件取得したい場合はfindAllを使用します。
詳細は次の記事を参照。
コメントでの指摘ありがとうございます。
$this->Book->findAll(array('Book.id <>'=>'2'));