yii2-collection icon indicating copy to clipboard operation
yii2-collection copied to clipboard

Similar interface to work with collection of models as with single model

Open rob006 opened this issue 7 years ago • 4 comments

Right now basic CRUD for model looks like this:

    public function actionCreate()
    {
        $model = new User();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }

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

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }

    public function actionDelete($id)
    {
        $this->findModel($id)->delete();

        return $this->redirect(['index']);
    }

When we need to work with tabular input and handle multiple instances of the same model in single request, things get more complicated (and still there is no docs for it).

ModelCollection could provide wrappers that makes this similar to CRUD for single model:


    public function actionCreate()
    {
        $collection = (new PostCollection())->fill(Post::className(), 10);

        if ($collection->load(Yii::$app->request->post()) && $collection->save()) {
            return $this->redirect(['index']);
        } else {
            return $this->render('create', [
                'collection' => $collection,
            ]);
        }
    }

    public function actionUpdate($ids)
    {
        /* @var $collection PostCollection */
        $collection = $this->findModels($ids);

        if ($collection->load(Yii::$app->request->post()) && $collection->save()) {
            return $this->redirect(['index']);
        } else {
            return $this->render('update', [
                'collection' => $collection,
            ]);
        }
    }

    public function actionDelete($ids)
    {
        $this->findModels($ids)->delete();

        return $this->redirect(['index']);
    }

Related: https://github.com/yiisoft/yii2/issues/14727

rob006 avatar Aug 28 '17 15:08 rob006

Actually there are multiple issues which will be solved (or at least simplified) by this:

https://github.com/yiisoft/yii2/issues/10877 and https://github.com/yiisoft/yii2/pull/10886 https://github.com/yiisoft/yii2/issues/10299 https://github.com/yiisoft/yii2/pull/11271 https://github.com/yiisoft/yii2/issues/14727 https://github.com/yiisoft/yii2/issues/7040

rob006 avatar Oct 08 '17 13:10 rob006

How would Collection::load() work on update? How will know which data belongs to each model? Or will it update the same data to all the found models?

Faryshta avatar Sep 02 '18 09:09 Faryshta

How would Collection::load() work on update?

In the same way as Model::loadMultiple()? It relies on order, so models and form data should be in the same order.

We could make it more complicated and use IDs (which should be passed in form) for records matching (then we could magically remove missing and add new records by using load() and save() only), but I'm not sure that is should be part of basic implementation. Let's keep it simple at the beginning and extend in the future.

rob006 avatar Sep 02 '18 12:09 rob006

Sounds good. Then how about having collection implement yii\db\ActiveRecordInterface?

Faryshta avatar Sep 03 '18 00:09 Faryshta