一个用户(user)可以发布多篇文章(post),多个不同的浏览者可以对一篇文章进行评论,一篇文章可以加上多个标签(tag)。为了满足这些需求,我们创建了几个表,users , posts, tags , posts_tags, comments。
users 表用来存放发布文章的作者信息,要发布文章必须是一个系统合法的用户。profiles 用来存放用户的详细资料,它一个user_id关联到users表的主键id,用来指定哪个用户。posts表来存放发布的文章,注意posts表的 user_id与users的主键id一致,用来表明发布文章的用户,注意,posts的user_id 的使用的是单数形式加上下划线再加上id。comments表用来存放文章的评论信息,post_id 与posts表的主键一致。posts_tags作为posts和tags之间的关联表,注意CakePHP不允许使用复合主键,因此也定义了自己的主键 id,post_id 和 tag_id 分别关联到posts表的主键id和tags表的主键id。
从这里可以看出,users 和profiles 是一个一对一的关系。
users和posts,posts和comments 是一对多的关系。
posts和tags是一个多对多的关系。
一对一
在Model中,使用$hasOne属性表示“拥有一个”的意思,一个用户拥有一个唯一的资料表,打开app/models/user.php中,添加$hasOne属性。
class User extends AppModel {
var $name = 'User';
var $hasOne=array('Profile');
}
?>
$hasOne定义为一个数组,你可以添加多个一对一的关系,如$hasOne=array('Model1' , 'Model2')。Profile 是关联表profiles 的Model名称,它也可以是一个数组。
class User extends AppModel {
var $name = 'User';
var $hasOne= array(
'Profile' => array('className' => 'Profile',
'foreignKey' => 'user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
?>
className 为所拥有的模型名称Profile。foreignKey为关联的外键名称,dependent设置模型之间的依赖关系,如果设置为true ,删除User时,会立即删除它所拥有的Profile模型。conditions可以添加查询条件。fields指定查询返回哪些字段。
在Profile中定义属性$belongsTo,指定Profile隶属于User这个模型。
class Profile extends AppModel {
var $name = 'Profile';
var $belOngsTo= array( 'User' );
}
?>
同样,这里使用了一种缩写格式。下面完整的表示方法。
class Profile extends AppModel {
var $name = 'Profile';
var $belOngsTo= array(
'User' => array('className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
?>
className 表示Profile从属于User,foreignKey指定关联的外键,conditions指定查询条件,fields指定返回的字段。
一对多
在Blog程序的模型的中,User和Post,Post和Comment都是一对多的代表。
在“一”的一端的模型中声明$hasMany属性。在“多”的一端的模型中声明$belongsTo属性。
class User extends AppModel {
var $name = 'User';
var $hasOne= array('Profile');
var $hasMany = array('Post');
}
?>
$hasMany 使用一个数组,存放包含模型的类名。它也可以使用完整的格式,嵌套一个数组。
var $hasMany = array(
'Post' => array('className' => 'Post',
'foreignKey' => 'user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
和$hasOne相比,这里多出了几个属性,可以设置offset , limit 来限制查询结果。还可以通过finderQuery , counterQuery 自定义查询语句和计数语句。
Post模型。
class Post extends AppModel {
var $name = 'Post';
var $belOngsTo= array('User');
var $hasMany = array('Comment');
}
?>
Comment 中定义一个$belongsTo ,指向Post。
class Comment extends AppModel {
var $name = 'Comment';
var $belOngsTo= array('Post');
}
?>
多对多
一篇文章可以指定多个tag ,一个tag 也可以应用到多个post之上,post与tag是多对多的关系。
在CakePHP中,多对多需要在模型两边指定$hasAndBelongsToMany属性,它融合了$hasMany和$belongsTo的概念,Post有多个tag,同时也属于某个tag。
Post模型。
class Post extends AppModel {
var $name = 'Post';
var $belOngsTo= array('User');
var $hasMany = array('Comment');
var $hasAndBelOngsToMany= array('Tag');
}
?>
完整的格式表示为。
var $hasAndBelOngsToMany= array(
'Tag' => array('className' => 'Tag',
'joinTable' => 'posts_tags',
'foreignKey' => 'post_id',
'associationForeignKey' => 'tag_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
它与$hasMany相比,又多出了几个属性,joinTable可以指定中间表的名称。associationForeignKey可以指定关联另一端在中间表的外键名称。可以自定义finderQuery , deleteQuery , insertQuery。
在Tag类中同样添加一个$hasAndBelongsToMany属性。
class Tag extends AppModel {
var $name = 'Tag';
var $hasAndBelOngsToMany= array('Post' );
}