yii2 中模型的不同字段 rest api

different fileds for a model in yii2 rest api

我在 yii2

中为休息 api 创建了自定义操作

我的代码是:

namespace app\controllers;
use yii\rest\ActiveController;
use yii\web\Response;
use Yii;
class RsController extends ActiveController{

    public $modelClass='app\models\Mymodel';
    /*some another actions*/

    public function actionOne($id){

        return \app\models\Anothermodel::findAll(['my_id'=>$id]);
    }


    public function actionTwo($id){
            return \app\models\Anothermodel::findAll(['my_name'=>'xxxx']);

    }
}

我知道我们可以覆盖模型中的 字段函数 来获取特殊字段,但是 现在我想为 actionOne 和 actionTwo(模型的)获取不同的字段 为此,我如何覆盖 Anothermodel 中的字段功能?

我从 here 找到了我的答案 我创建了一个这样的组件

<?php

namespace app\components;


class Serializer extends \yii\rest\Serializer {

    public $defaultFields;
    public $defaultExpand;

    public function init() {
        parent::init();
        $this->defaultFields = !is_null($this->defaultFields) ? implode(",", $this->defaultFields) : $this->defaultFields;
        $this->defaultExpand = !is_null($this->defaultExpand) ? implode(",", $this->defaultExpand) : $this->defaultExpand;
    }

    protected function getRequestedFields() {
        $fields = is_null($this->request->get($this->fieldsParam)) ? $this->defaultFields : $this->request->get($this->fieldsParam);
        $expand = is_null($this->request->get($this->expandParam)) ? $this->defaultExpand : $this->request->get($this->expandParam);

        return [
            preg_split('/\s*,\s*/', $fields, -1, PREG_SPLIT_NO_EMPTY),
            preg_split('/\s*,\s*/', $expand, -1, PREG_SPLIT_NO_EMPTY),
        ];
    }

}

然后在我的控制器操作中设置我的字段 像这样。

public function actionOne($id){
      $this->serializer['defaultFields'] = ["field1",
        "field2"];
        return new \yii\data\ActiveDataProvider([
            'query' => \app\models\Anothermodel::find()->where(['my_id'=>$id]),
        ]);
    }


   public function actionTwo($id){
         $this->serializer['defaultFields'] = ["field1",
         "field2","field3"];
        return new \yii\data\ActiveDataProvider([
            'query' => \app\models\Anothermodel::find()->where(['my_id'=>$id]),
        ]);
    }

我建议使用events

public function actionPublic()
{
    \yii\base\Event::on(Thing::class, Thing::EVENT_AFTER_FIND, function ($event) {
        $event->sender->scenario = Thing::SCENARIO_SEARCH_PUBLIC;
    });
    return new ActiveDataProvider([
        'query' => Thing::find(),
    ]);
}


public function actionPrivate()
{
    \yii\base\Event::on(Thing::class, Thing::EVENT_AFTER_FIND, function ($event) {
        $event->sender->scenario = Thing::SCENARIO_SEARCH_PRIVATE;
    });
    return new ActiveDataProvider([
        'query' => Thing::find(),
    ]);
}

并在 ActiveRecord 内部(在我的例子中是 Thing)检查 fields() 方法中的场景

 public function fields()
 {
    $fields = parent::fields();

    if ($this->scenario === self::SCENARIO_SEARCH_PUBLIC) {
        unset($fields['field1'], $fields['field2'], $fields['field3'], $fields['field4']);
    }

    return $fields;
  }

检查我在 gihub

中的回答