Yii2 RESTful API开发的相关模型

通过 yii2\rest\ActiveController 可以方便的用几行代码创建针对某个资源的api,但是默认是最简单的逻辑,并不支持对 relatedModel的操作。这里做一个扩展。
参考GitHub 项目地址: https://github.com/Ganiks/yii2rest
还是建议将 \yii\rest\ 拷贝出来另作一个命名空间,在这个基础上做扩展

针对 view create update delete 操作,下面尝试实现一个common 通用的方案

view

    public function run($id)
    {
        $model = $this->findModel($id);
        return $model;
    }

这里action不需要做任何修改了,因为在 model中定义的fields已经可以同时将relatedModel数据返回了。

	public function getNewsItem()
	{
		return $this->hasOne(NewsItem::className(), ['header_id' => 'id']);
	}

    /**
     * @inheritdoc
	 * 如果没有指定fields ,默认返回这里定义的所有字段
	 * 如果指定了fields则只返回指定的字段
     */
	public function fields()
	{
		return [
			'id',
			'image',
			'link',
			'newsItem',
		];
	}

create

    public function run()
    {
        if ($this->checkAccess) {
            call_user_func($this->checkAccess, $this->id);
        }

        /* @var $model \yii\db\ActiveRecord */
        $model = new $this->modelClass([
            'scenario' => $this->scenario,
        ]);

		#NewsItem || newsItem 不区分大小写
		$modelItem = str_ireplace($this->controller->id, $model->relations(), $this->modelClass);
		$modelItem = new $modelItem;

        $model->load(Yii::$app->getRequest()->getBodyParams(), '');
		$modelItemParam = Yii::$app->getRequest()->getBodyParams()[$model->relations()];
		$modelItem->load($modelItemParam, '');
        if ($model->save()) {
            $response = Yii::$app->getResponse();
            $response->setStatusCode(201);
            $id = implode(',', array_values($model->getPrimaryKey(true)));
			$modelItem->header_id = $id;
			$modelItem->save();
            $response->getHeaders()->set('Location', Url::toRoute([$this->viewAction, 'id' => $id], true));
        }

        return $model;
    }

create方法的关键是得到relatedModel的全路径 app\models\relatedModel

@$this->controller->id=news
@model->relations()=newsItem
@this->modelClass=app\models\news
$modelItem = str_ireplace($this->controller->id, $model->relations(), $this->modelClass);

这里的 model->relations() 是自己在 app\model\NewsItem中定义的,后面还要用到:

    /**
     * @inheritdoc
	 * 自定义参数,让 $model->relations 获取到关联的 model 
     */
	public function relations()
	{
		return 'newsItem';
	}

update

    public function run($id)
    {
        /* @var $model ActiveRecord */
        $model = $this->findModel($id);

        if ($this->checkAccess) {
            call_user_func($this->checkAccess, $this->id, $model);
        }

        $model->scenario = $this->scenario;
		/*
		 *
		 * x-www-form-urlencoded key=>value
		 * image mmmmmmmm
		 * link  nnnnnnnnnn
		 * newsItem[title]=>ttttttttttt , don't use newsItem["title"]
		 * newsItem[body]=>bbbbbbbbbbb
		 * don't use newsItem=>array("title":"tttttt","body":"bbbbbbb")
		 * don't use newsItem=>{"title":"ttttttt","body":"bbbbbbbb"}
		 *
		 */
		$params = Yii::$app->getRequest()->getBodyParams();
		$model->load($params, '');
		$itemParam = array_diff_key($params, $model->attributes);
		$itemModel = array_keys($itemParam)[0];
		$itemRelation = $model->relations(); 
		if($model->save())
		{
			if($itemParam && $itemModel == $itemRelation) {
				$model->$itemModel->load($itemParam[$itemModel], '');
				$model->$itemModel->save();
			}
		}

        return $model;
    }

delete

    public function run($id)
    {
        $model = $this->findModel($id);

        if ($this->checkAccess) {
            call_user_func($this->checkAccess, $this->id, $model);
        }

		$itemRelation = $model->relations(); 
		if($model->delete()) {
			if($itemRelation) {
				$model->$itemRelation->delete();
			}
		}
		
        Yii::$app->getResponse()->setStatusCode(204);
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值