Changes
Title
unchanged
How to add a named scope to ActiveRecords with a behavior
Category
unchanged
Tutorials
Yii version
unchanged
Tags
unchanged
Content
changed
[...]
// ...
}
```
That's it. Our named scope is ready to use with `Post`. Feel free to improve the above code or come up with your own ideas for named scopes that are good candidates for a behavior.
some improvement:
```php
class BetweenBehavior extends CActiveRecordBehavior
{
/**
* @var string
* here you can config it if you have a different name from 'CreateAt'
*/
public $attrCreateAt = 'CreatedAt ';
/**
* @param $start
* @param $end
* @param null $alias
* you can specify an alias here which can be the current ActiveRecord( normally is 't') or relation Ar 's alias(the relation name)
* @return CActiveRecord
*/
public function between($start,$end,$alias=null)
{
$alias = empty($alias)? $this->getOwner()->getTableAlias(false) : $alias;
if(empty($alias)){
$condition = $this->attrCreateAt.' BETWEEN :start AND :end';
}else{
$condition = $alias.'.'.$this->attrCreateAt.' BETWEEN :start AND :end';
}
$this->Owner->getDbCriteria()->mergeWith(array(
'condition'=> $condition,
'params'=>array(':start'=>$start, ':end'=>$end)
));
return $this->Owner;
}
}
usage:
class Post extends CActiveRecord {
// ...
public function behaviors()
{
return array(
'BetweenBehavior' => array(
'class'=>'BetweenBehavior',
'attrCreateAt' = 'createTime',
)
);
}
// ...
}
// with relation query ,the CreateAt is from Comment class. haven't test this funcitonality
$posts=Post::model()->between($start,$end,'comments')->with('comments')->findAll();
```
***
# 如何用行为(behavior)给数据记录(ActiveRecords)添加命名范围
从yii 1.0.5版本开始你可以使用ActiveRecords的命名范围(Name scopes),对于我们简化数据库的查询请求有很大的帮助,例如,你有很多带有"CreateAt"的数据表,它是一个整数的UNIX的时间戮,现在我们想添加一个命名范围 between($start,$end),我们数据记录都可以方便的使用如下查询方法。
~
```php
$start = strtotime('2009-01-01');
$end = strtotime('2009-12-31');
Post::model()->between($start,$end)->findAll($someCriteria);
```~
这个查询返回所有符合($someCriteria)条件并且创建时间是在$start和$end之间的Post。
下面开始来学习命名范围,Named scopes 通常定义在ActiveRecord的一个叫做"scope"的方法内,因为我们的(Name scope)有参数,所以我们需要定义一个更加明确的方法。
~
```php
public function between($start,$end){
$this->getDbCriteria()->mergeWith(array(
'condition'=>'CreatedAt BETWEEN :start AND :end',
'params'=>array(':start'=>$start,':end'=>$end)
));
return $this;
}
```~
我们可以把这个方法添加到一个(ActiveRecord),between这个方法就可以被这个ActiveRecord使用了,但是如果我们想让我们的所有models都有个有功能,我们就可以使用(behavior),我只需要把上面的代码添加到一个Class里面简单修改一下就行了。
~
```php
class BetweenBehavior extends CActiveRecordBehavior{
public function between($start,$end){
$this->Owner->getDbCriteria()->mergeWith(array(
'condition'=>'CreatedAt BETWEEN :start AND :end',
'params'=>array(':start' =>$start,':end' =>$end)
));
return $this->Owner;
}
}
```~
我们可以把这个保存为一个文件,BetweenBehavior.php,把它放到一个程序可以自动导入的文件夹中(可导入文件夹),最后我们必须向我们所有的model添加这个行为,要实行这个功能我们向model添加一个behaviors方法。
~
```php
class Post extends CActiveRecord{
public function behaviors(){
return array(
'BetweenBehavior' => array('class' => 'BetweenBehavior')
);
}
}
```~
就是这样了,我们的named scope就这样添加到Post里面了。随意改善以上代码,你可以有自己更好的想法来利用named scope。对于behavior这是一个好的候选方法。