官方资料:
http://www.yiiframework.com/doc-2.0/guide-db-active-record.html
http://www.yiiframework.com/doc-2.0/guide-rest-quick-start.html
一些补充
activecontroller的各种action是可以重载的,但必须先要unset掉父类的方法。
比如下面这样,注意里面的actions()方法,如果这里没有unset掉父类方法的话,重载的function actionXXX不会起作用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?php namespace app\modules\rest\v2\controllers; use Yii; use yii\data\ActiveDataProvider; use app\models\db\Task; use app\models\db\TaskSearch; class TaskController extends BaseActiveController { public $modelClass = 'app\models\db\Task' ; public function actions() { $actions = parent::actions(); unset( $actions [ 'index' ]); return $actions ; } public function actionIndex() { $searchModel = new TaskSearch(); $dataProvider = $searchModel ->search(Yii:: $app ->request->queryParams); return $dataProvider ; } } |
这里调用的TaskSearch类仿照了gii生成的ModelSearch类,TaskSearch类的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | <?php namespace app\models\db; use Yii; use yii\base\Model; use yii\data\ActiveDataProvider; use app\models\db\Task; class TaskSearch extends Task { public $keyword ; /** * @inheritdoc */ public function rules() { return [ [[ 'projectId' , 'keyword' ], 'string' ], [ 'main_type' , 'in' , 'range' => self::getEnumColumnValues( 'main_type' )], [ 'type' , 'in' , 'range' => self::getEnumColumnValues( 'type' )], [ '_status' , 'in' , 'range' => self::getEnumColumnValues( '_status' )], [ 'publish_status' , 'in' , 'range' => self::getEnumColumnValues( 'publish_status' )], ]; } /** * @inheritdoc */ public function scenarios() { // bypass scenarios() implementation in the parent class return Model::scenarios(); } /** * Creates data provider instance with search query applied * * array $params * * ActiveDataProvider */ public function search( $params ) { $this ->load( $params , '' ); if (! $this ->validate()) { return ( new \yii\rest\Serializer())->serialize( $this ); } $query = Task::find(); $dataProvider = new ActiveDataProvider([ 'query' => $query , 'pagination' => [ 'defaultPageSize' => self::DEFAULT_PAGE_SIZE, 'pageSizeParam' => 'page_size' , 'pageSizeLimit' => [0, 100], ], ]); $query ->andFilterWhere([ 'projectId' => $this ->projectId, 'main_type' => $this ->main_type, 'type' => $this ->type, '_status' => $this ->_status, 'publish_status' => $this ->publish_status, ]); $query ->andFilterWhere([ 'like' , 'name' , $this ->keyword]); return $dataProvider ; } } |
这里面的
$this->load($params, '');
需要加上第二个参数,因为和activeform的表单提交不同,这里的输入只是一维数组而不是两维。
'defaultPageSize' => self::DEFAULT_PAGE_SIZE
默认的每页记录数(querystring内没有提供的情况下),如果没有这行,Yii2给的默认值是20
'pageSizeParam' => 'page_size'
每页记录数的querystring名称,默认是'per-page'。
'pageSizeLimit' => [0, 100]
如果page_size=0表示无分页限制,取出所有的纪录。这个值默认是[1, 50],防止page_size过大影响性能。
if (!$this->validate()) {
return (new \yii\rest\Serializer())->serialize($this);
}
这一段可以直接格式化输出错误内容,并且将Http status code改成4xx(表示客户端错误)。
mongodb也有一个activerecord类:
https://github.com/yiisoft/yii2-mongodb/blob/master/docs/guide/usage-ar.md
使用的时候发现一些问题
mongodb的objectId并不是纯数字,put/get one/delete方法会报404错误,所以yii的路由规则要加上一段,类似:
1 | [ 'class' => 'yii\rest\UrlRule' , 'controller' => [ 'rest/v2/tasklogs' => 'rest-v2/task-log' ], 'tokens' => [ '{id}' => '<id:\\w[\\w,]*>' ]], |
存日期类型的话要像下面一样
1 2 3 | $this ->_created = new \MongoDate(); // yii2-mongodb v2.0.x $this ->_created = new \Mongodb\BSON\UTCDateTime( round (microtime(true))*1000); // yii2-mongodb v2.1.x |
输出显示的时候
1 | $this ->_created = $this ->_created->toDateTime()->setTimezone( new \DateTimeZone( 'Asia/Shanghai' ))->format( "Y-m-d H:i:s" ); |
attributes和rules方法,attributes表示查询后输出显示的字段,rules里面控制的是输入验证的字段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * @inheritdoc */ public function attributes() { return [ '_id' , 'message' , 'data' , '_created' , '_updated' ]; } /** * @inheritdoc */ public function rules() { return [ [[ 'message' , 'data' ], 'safe' ], ]; } |
page_size值等于0的时候,只返回一条记录,而不是所有,这里有个bug
yii2-mongodb/Command.php下面(目前版本v2.1.2),603行
if ($options['limit'] === null) {
应该改成
if ($options['limit'] === -1) {