Yii2覆盖在Rest ActiveController中的泛型创建动作

时间:2014-12-25 15:24:15

标签: rest yii2

我在Yii2中有一个Rest API,Yii生成所有动作

查看/更新/创建/删除

我想更改createMethode和其他方法的comportement,所以我不能使用类Controller,我应该使用类ActiveController

但是我希望那个类做同样的工作,我需要在创建之前添加一些动作并在创建之后添加一些动作。所以我需要覆盖actionCreate

我该怎么办?

3 个答案:

答案 0 :(得分:32)

您可以执行以下操作

class CountryController extends ActiveController
{
    public $modelClass = 'common\models\Country';

    public function actions()
    {
        $actions = parent::actions();
        unset($actions['create']);
        return $actions;
    }

    public function actionCreate(){
        // implement here your code

    }

}

答案 1 :(得分:2)

我知道这是一个老问题;但我发现它在一个相关的搜索中,并认为我可以提供一个很好的,更新的解决方案和现在的内容摘要。希望有人发现这有用......

我知道有两种方法可以做到这一点。您可以定义一个操作方法,如@Roman Podlinov所提到的,或者您可以将操作定义为单独的类,并将默认的创建操作指向它,接近@ mrJ0ul3提到的内容。为了完整起见,我将在下面提供两个例子。

方法1 - 控制器中的动作方法

在控制器中,覆盖actions方法,如下所示:

public function actions()
{
    $actions = parent::actions();
    unset($actions['create']);
    return $actions;
}

然后您可以在该控制器中定义您的创建方法。

public function actionCreate()
{
    // your code goes here
}

要明确的是,方法名称确实需要为actionCreate,如上所示。我看到提到createAction的评论,但这是不正确的。他们可能会混淆CreateAction类,它是yii \ rest命名空间的一部分,并保存实际使用默认REST创建操作运行的代码。但是,如果使用此方法覆盖创建请求逻辑,那么该类并不重要。对于另一种方法,它确实很重要......

方法2 - 单独的动作类

就个人而言,我更喜欢并使用此方法来覆盖默认操作。我喜欢将默认的CRUD动作逻辑保留在控制器本身之外。很高兴知道如果我的控制器中有动作方法,它们就是完全自定义动作。这绝对只是个人偏好。

为此,您将创建一个新的类文件,其中应包含如下所示的代码:

namespace app\actions\controllerName

class CreateAction extends \yii\rest\CreateAction
{
    public function run()
    {
        // your code goes here
    }
}

如果你选择这条路线,我建议你查看Yii的REST CreateAction类的主体,并在你的代码之后模拟代码的进展,假设你的用例是有意义的。

现在您只需告诉控制器将此动作类用于创建动作。你可以在控制器的actions方法中这样做:

public function actions()
{
    $actions = parent::actions();
    $actions['create']['class'] = 'app\actions\controllerName\CreateAction';
    return $actions;
}

正如您所看到的,它在语法上与@ mrJ0ul3建议的相似;但这个建议只改变了一个行动的一部分如何运作。它不允许你完全覆盖动作的逻辑 - 这就是为什么它在回答实际问题时错过了标记。

希望有所帮助!

- 每个人! :)

答案 2 :(得分:-1)

或者您可以按照以下步骤操作:

public function actions() {
    $actions = parent::actions();
    // will overriding return data on the index action
    $actions['index']['prepareDataProvider'] = [new app/models/Post(), 'getAllPost'];
    return $actions;
}