Containable使用方法

edited 十月 2013 in CakePHP
首先,要知道cake的behaviors是怎么用。唠叨一句,cake里的behaviors是拿来扩展model的。

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

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

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

载入behaviors,最简单的方法当前就是在Model里加上,如:

1. <?php
2. class AppModel extends Model {
3. var $actsAs = array(
4. 'Containable'
5. );
6. }
7. ?>

忘了介绍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的强大,呵呵!废话不说,说说它是如何使用的吧。

按照上面的代码,载入所需的behaviors,如果你只想在特定环境用一次的话,那么就动态载入

1. $model->Behaviors->attach('Containable');

因为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、我只想取出用户所对应的文章

1. $userModel->contain('Article');
2. $data = $userModel->find('all');

2、我想取出用户所对应的文章,以及文章所拥有的评论

1. $userModel->contain('Article.Comment');
2. //或者
3. $userModel->contain(array('Article' => 'Comment'));
4. $data = $userModel->find('all');

3、我只想取出用户对应文章的标题

1. $userModel->contain('Article(title)');
2. $data = $userModel->find('all');

4、我想取出用户对应的文章,以及文章对应的评论,以及评论所对应的用户

1. $userModel->contain(array('Article' => array('Comment' => 'User')));

5、我想取出用户对应文章的标题,但是这些文章的条件是is_top=1

1. $userModel->contain(array('Article' => array('fields' => array('title'), 'conditions' => array('is_top' => 1))));

........依此类推吧,大概就这样。

如何在分页里使用呢。很简单,拿上面的例子来说。

1. $this->paginate = array('User' => array('fields' => array('title'), 'contain' => array('Article(title)')));

有人说,分页时,我也用

1. $userModel->contain('Article');

好像结果不对。那就对了,因为分页时,Model其实find了两次了,一次是find count取总数,一次是取出当页数据。而每次find时,默认reset为true,所以find结束后,都会resetAssociations一下,重置当前的Model关联。所以换个方法

1. $userModel->contain(false, array('Article'));

第一个参数如果为布尔值的话,那么会当成reset参数传递进去了。
更多请参考cakephp教程系列

原始討論: http://twpug.net/x/modules/newbb/viewtopic.php?topic_id=3814

評論

Sign In or Register to comment.