忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2017/05/01 15:13 |
CakePHP-04:CakePHPで複数のテーブル結合続き

前回ので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
<?php
    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
<?php
    //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


2009/10/30 22:11 | Comments(0) | TrackBack(1) | PHP

トラックバック

トラックバックURL:
cakePHPのDBアクセスは、基本的にはモデル作って関係を記述してコントローラからfindするだけで自動的に行ってくれます。 が、これだと常に全フィールドをそのまま持っくることしかできません。 "MIN(books.id)"が欲しい、といった場合はfind内に記述することで実現できます。 $this->Book->find(''all'',array(''fields''=>''MIN(Book.id) AS hoge''));...
弱小PHPerの憂鬱 | 2009/11/02 19:54

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<買った本リスト 2009/11/01 | HOME | ゲームレビュー:メモリーズオフ6 T-Wave>>
忍者ブログ[PR]