2009年4月27日星期一

Containable使用方法

本文章最初出自于Just popping in之手..

要知道cake的behaviors是怎么用。cake里的behaviors是拿来扩展model的。

model 里提供了好多回调函数,诸如 beforeSave afterSave beforeDelete.....等等,这些方法,在behaviors里同样适用。只不过,model调用这些回调函数时,默认把当前model实例当 成第一个参数传入。所以behaviors的方法,如果想让外部可用,那么函数名大概为

[php]
function myFunc(&$model, $参数1, $参数2...) {
//doSomeThing
}
[/php]

使用时,载入当前behaviors,然后$model->myFunc($参数1, $参数2...);

载入behaviors,最简单的方法当前就是在Model里加上,如:
[php]
class AppModel extends Model {
var $actsAs = array(
'Containable'
);
}
[/php]
忘 了介绍Containable是干什么用的了。经常听到人说,“我Model间使用了很多关联,怎么样才能取到所需的数据,减少不必要的数据库操作呢?”。Containable就是拿来干这事儿的。当然Model里有recursive属性,但是这个不怎么人性化,虽然有-1 0 1 2等等几级可以设置关联,但是同一级之间,我想取消到不必要的关联,这办法就不管用了。顺便说一句,要想取消掉当前Model所有关联,recursive应该设置为-1,而不是为0。如果为0的话,当前Model还会关联belongsTo和hasOne的Model。

Model 里还有bindModel和unbindModel方法,但是查出来垃圾数据太多啦……@#&%……¥。想不通的是,cake为什么不把Containable写到Model内部里去,而非要当成behaviors使用。难道是为了证明behaviors的强大

因为Containable比较实用,所以可以在Model基类,即AppModel就载入这个Behaviors了。

假如

User hasMany Article

User hasOne Profile

User belongsTo Group

User hasAndBelongsToMany Role

Article hasMany Comment

Comment belongsTo User

......

若当前对User Model进行操作。

1、只想取出用户所对应的文章
[php]
$userModel->contain('Article');
$data = $userModel->find('all');
[/php]

2、想取出用户所对应的文章,以及文章所拥有的评论
[php]
$userModel->contain('Article.Comment');
$userModel->contain(array('Article' => 'Comment'));
$data = $userModel->find('all');
[/php]
3、我只想取出用户对应文章的标题
[php]
$userModel->contain('Article(title)');
$data = $userModel->find('all');
[/php]
4、我想取出用户对应的文章,以及文章对应的评论,以及评论所对应的用户
[php]
$userModel->contain(array('Article' => array('Comment' => 'User')));
[/php]
5、我想取出用户对应文章的标题,但是这些文章的条件是is_top=1
[php]
$userModel->contain(array(
'Article' => array(
'fields' => array('title'),
'conditions' => array('is_top' => 1))
)
);
[/php]
........依此类推吧,大概就这样。

如何在分页里使用呢? 很简单,拿上面的例子来说..
[php]
$this->paginate = array(
'User' => array(
'fields' => array('title'),
'contain' => array('Article(title)')
)
);
[/php]
有人说,分页时,我也用
[php]
$userModel->contain('Article');
[/php]
好像结果不对。那就对了,因为分页时,Model其实find了两次了,一次是find count取总数,一次是取出当页数据。而每次find时,默认reset为true,所以find结束后,都会resetAssociations一下,重置当前的Model关联。所以换个方法
[php]
$userModel->contain(false, array('Article'));
[/php]
第一个参数如果为布尔值的话,那么会当成reset参数传递进去了...

更进一步,使用condition 的方式..
[php]
* $post->contain(array(
'User'=>array(
'conditions'=>array(),
'fields' =>array(
'User.username',
'User.email')
'limit'=>...
)));
[/php]
就跟model::find的参数一样...

没有评论 :

发表评论