Ngu ngơ học làm web (x4) - CakePHP2 - Quan hệ bảng Containable

-----

Phần x4. CakePHP2 – Quan hệ bảng Containable


Xem (clip số 8 – chickenrainshop):

Giải thích về mối quan hệ một – nhiều (phút 0:39).

- một – nhiều

(hasMany >) – (< belongsTo)

Ví dụ:

(hasMany)

- Một book thì có một hoặc nhiều comment (một cuốn sách có thể có một hoặc nhiều nhận xét)

- Một category thì có nhiều book (một lĩnh vực có thể có một hoặc nhiều cuốn sách).

(belongsTo)

- Một comment thì phải thuộc về một book nào đó

- Một book thì phải thuộc về một category nào đó

Mối quan hệ này được thiết lập ngay từ khi tạo bảng, để ý trong bảng comments sẽ có trường book_id, nghĩa là nó đã ngầm định là comment này phải thuộc về book có id là book_id nào đó. Tương tự, trong bảng book, sẽ có trường category_id.

Khi thực hiện sinh mã tự động bằng Cake console, thì mối quan hệ này lại tiếp tục được ghi vào trong model. Tất nhiên, người lập trình vẫn có thể thiết lập và chỉnh sửa các thông tin này.

Ví dụ,

[Book model]

public $belongsTo = array(
                        'Category' => array(
                                    'className' => 'Category',
                                    'foreignKey' => 'category_id',
                                    'conditions' => '',
                                    'fields' => '',
                                    'order' => ''
                        )
            );

public $hasMany = array(
                        'Comment' => array(
                                    'className' => 'Comment',
                                    'foreignKey' => 'book_id',
                                    'dependent' => false,
                                    'conditions' => '',
                                    'fields' => '',
                                    'order' => '',
                                    'limit' => '',
                                    'offset' => '',
                                    'exclusive' => '',
                                    'finderQuery' => '',
                                    'counterQuery' => ''
                        )
            );

[Comment model]

public $belongsTo = array(
                        'User' => array(
                                    'className' => 'User',
                                    'foreignKey' => 'user_id',
                                    'conditions' => '',
                                    'fields' => '',
                                    'order' => ''
                        ),
                        'Book' => array(
                                    'className' => 'Book',
                                    'foreignKey' => 'book_id',
                                    'conditions' => '',
                                    'fields' => '',
                                    'order' => ''
                        )
            );

- nhiều – nhiều

(hasAndBelongsToMany >) – (< hasAndBelongsToMany)

Ví dụ, book – writer

- Một cuốn sách có thể được viết bởi nhiều người và ngược lại một người cũng có thể viết nhiều cuốn sách.

Mối quan hệ này cũng được thiết lập ngay từ  khi tạo bảng, bằng cách ra tạo một bảng phụ để thể hiện mối quan hệ này, ví dụ bảng books_writers.

Khi thực hiện sinh mã tự động bằng Cake console, thì mối quan hệ này lại tiếp tục được ghi vào trong model.

Ví dụ,

[Book model]

public $hasAndBelongsToMany = array(
                        'Writer' => array(
                                    'className' => 'Writer',
                                    'joinTable' => 'books_writers',
                                    'foreignKey' => 'book_id',
                                    'associationForeignKey' => 'writer_id',
                                    'unique' => 'keepExisting',
                                    'conditions' => '',
                                    'fields' => '',
                                    'order' => '',
                                    'limit' => '',
                                    'offset' => '',
                                    'finderQuery' => '',
                        )
            );

[Writer model]

public $hasAndBelongsToMany = array(
                        'Book' => array(
                                    'className' => 'Book',
                                    'joinTable' => 'books_writers',
                                    'foreignKey' => 'writer_id',
                                    'associationForeignKey' => 'book_id',
                                    'unique' => 'keepExisting',
                                    'conditions' => '',
                                    'fields' => '',
                                    'order' => '',
                                    'limit' => '',
                                    'offset' => '',
                                    'finderQuery' => '',
                        )
            );

Xem (clip số 9 – chickenrainshop):

Sử dụng behavior Containable để lấy dữ liệu từ các bảng có mối quan hệ với nhau (thay thế cho recursive) (phút 1:43)

- Khai báo trong model là sẽ sử dụng Containable,

class Book extends AppModel {
            public $actsAs = ['Containable'];

- Ví dụ, trong controller Books, để lấy thêm dữ liệu từ hai bảng Writers và Comments, sử dụng thêm tùy chọn contain trong hàm find(), cú pháp là:

‘contain’ => [‘bảng1’, ‘bảng 2’]

Hoặc phức tạp hơn, hạn chế số field của các bảng lấy thêm.

‘contain’ => [
‘bảng 1’ => [‘fields’ => [
                        ‘tên trường 1’, ‘tên trường 2’
]
],
‘bảng 2’ => [‘fields’ => [
                        ‘tên trường 1’, ‘tên trường 2’
]
]
]

Ví dụ,

public function truyvan(){
                        $books = $this->Book->find('all', [
                                    'contain' => ['Writer', 'Comment']
                                    ]);
                        pr($books);exit;
            }

Hạn chế số field của hai bảng lấy thêm:

public function truyvan(){
                        $books = $this->Book->find('all', [
                                    'fields' => ['id', 'title'],
                                    'contain' => [
                                                'Writer' => [
                                                            'fields' => ['id', 'name']
                                                            ],
                                                'Comment']
                                    ]);
                        pr($books);exit;

            }
-----------
Cập nhật 23/4/2017
-----------
Xem thêm:
Tổng hợp các bài viết về Ngu ngơ học làm web