译文

CakePHP应用开发 第六章 对象关系映射(ORM):构建表关系 (7)

翻译:Moon.Wong | 2010-01-08 12:06:54 | 阅读213 | 来源

上一篇|目录|下一篇

使用复杂关联

多对多的关系需要一个额外的表来将相关的两张表关联起来。在这一部分,我们将学习如何在模型中为多对多的表关系定义关联。接下来,我将了解如何使用这种特殊的模型关联来在数据库表中检索,删除和保存相关数据。

在模型中定义多对多的关系

在先前的例子中,我们假定了一本书只能有一个作者。但是在现实生活中,一本书可能会有多个作者。在这种情况下,作者和图书之间的关系是多对多关系。我们接下来将了解如何为多对多关系定义模型关联。我们将会修改本章节前面已经在使用的现成代码,为其设置好所需关联类型以表示这种多对多的关系。

动手时间:定义多对多关系

1,清空数据库表:   

TRUNCATE TABLE `authors`;   

TRUNCATE TABLE `books`;

2,从books表中移除author_id字段   

ALTER TABLE `books` DROP `author_id`

3,创建一个新表,表名为author_books:  

  CREATE TABLE `authors_books` (`author_id` INT NOT NULL ,  `book_id` INT NOT NULL)

4,修改Author模型(/app/models/author.php):  

        class Author extends AppModel
    {
       var $name = 'Author';    
        var $hasAndBelongsToMany = 'Book';
    }
    ?>

5,修改Book模型(/app/models/book.php): 

        class Book extends AppModel
    {
       var $name = 'Book';    
        var $hasAndBelongsToMany = 'Author';
    }
    ?>

6,修改Authors控制器(/app/controllers/authors_controller.php): 

          class AuthorsController extends AppController {
             var $name = 'Authors';
             var $scaffold;
    }
    ?>

7,修改Books控制器 (/app/controllers/books_controller.php): 

         class BooksController extends AppController {
        var $name = 'Books';
        var $scaffold;
    }
    ?>

8,访问下面两个连接,然后向系统中添加一些测试数据:

http://localhost/relationship/authors/

http://localhost/relationship/books/

 


怎么回事?

首先,我们清空了数据库,接着我们删除(drop)掉books表中的author_id字段。接着我们添加了一个新的联接表authors_books,这个表将会用被来为authors表和books创建多对多的关系。下面这张图表展示了一个联接表是如何将多对多关系中的两张表关联起来。


在多对多关系中,某表中的一条记录在另外一张表中都有多条相关的记录。为了构建这种联系,我们使用了一个联接表——联接表中有两个字段,它们是用来保存相关两张表中的主键的。

CakePHP对于关联表也有确定的命名规则——关联表必须以相关两张表的表名来命名,两个表名谁前谁后,按字母排序,其中两个表名之间用下划线联接。因 此authors和book表之间的联接表应该命名为authors_books,而非books_authors。另外因为CakePHP的命名规则, 联接表中的外键必须是相关模型名的单数加下划线形式,并且后面有一个_id后缀。

创建联接表后,我们接着在模型中定义了关联,以便我们的模型也知道他们之间的新关联类型。我们在两个模型中添加了多对多类型的关联 (hasAndBelongsToMany 简写HABTM),HABTM是模型中用来定义多对多关系的一种特殊关联。模型两边都用HABTM关联来定义这种多对多的关系。在模型中定义好这种关联后,我们为这两个模型创建了两个控制器,并在其中添加了脚手架属性以便查看这种关联是否已经起作用。

我们也可以使用数组来在模型中设置HABTM关联。下面这段代码展示了如何使用数组来在Author模型中设置authors和books表之间的这种多对多关联。

var $hasAndBelongsToMany = array(
        'Book' =>
            array(
             'className'              => 'Book',
                'joinTable'              => 'authors_books',
                'foreignKey'             => 'author_id',
                'associationForeignKey'  => 'book_id'
            )
        );

跟之前简单的关系一样,我们也可以通过添加,修改这个关联数组中的键值对来覆盖默认的关联参数。外键(foreignKey)键值对存有当前模型中外键的名称——默认的是当前模型名的下划线,单数形式,后面再添加一个_id后缀。而关联外键的键值对则保存有对应模型中的外键名——默认的是关联模型名的单数下划线形式,并有一个_id后缀。我们也可以添加conditions(条件), fields(字段),以及 order(排序)等键值对来对这种关联做更详细的设置。(译者:应该跟之前一对多关联的类似。)

【本文翻译仅为外语学习及阅读目的,原文作者个人观点与译者及译言网无关】

分享:

添加评论