CRUD Operations in Yii2

Yii2 provides built-in support for performing CRUD (Create, Read, Update, Delete) operations using Active Record and Gii code generator. In this tutorial, we’ll explore:

  1. Using Gii to generate CRUD operations (Default Yii2 approach).
  2. Using a Form Model for handling CRUD operations (Recommended by Dynamic Duniya).

1. Generating CRUD Using Gii (Default Yii2 Approach)

Yii2 provides Gii, a powerful code generator tool that can generate CRUD operations for a model.

Step 1: Enable Gii

If you haven't enabled Gii in your Yii2 project, add the following code to config/web.php:

'modules' => [
    'gii' => [
        'class' => 'yii\gii\Module',
    ],
],

Access Gii at:
 http://your-app-url/index.php?r=gii

Step 2: Generate CRUD Code

  1. Click on "CRUD Generator" in Gii.
  2. Enter the Model Class (e.g., app\models\MasterState).
  3. Enter the Search Model Class (optional, e.g., app\models\MasterStateSearch).
  4. Enter the Controller Class (e.g., app\controllers\MasterStateController).
  5. Click Preview, then Generate.

This will generate:

  • Model (MasterState.php): Defines database structure.
  • Search Model (MasterStateSearch.php): Handles filtering in GridView.
  • Controller (MasterStateController.php): Manages CRUD actions.
  • Views (views/master-state/): Contains index.php, create.php, update.php, view.php, and _form.php.

Step 3: Perform CRUD Operations

Now, you can access:

  • List records: http://your-app-url/index.php?r=master-state/index
  • Create a record: http://your-app-url/index.php?r=master-state/create
  • Update a record: http://your-app-url/index.php?r=master-state/update&id=1
  • Delete a record: http://your-app-url/index.php?r=master-state/delete&id=1

2. Using a Form Model for CRUD Operations (Recommended by Dynamic Duniya)

Instead of using Active Record directly in views, we can use a Form Model to handle form submission, validation, and save logic. This is useful when we need:

  • Custom form handling.
  • Additional validation rules.
  • Business logic before saving data.

Step 1: Create a Form Model

Create a new Form Model inside modules/location/models/form/MasterStateForm.php:

namespace app\modules\location\models\form;

use Yii;
use app\modules\location\models\MasterState;
use app\modules\location\models\MasterZone;
use yii\base\Model;
use yii\helpers\ArrayHelper;

class MasterStateForm extends Model
{
    public $state_code;
    public $state_name;
    public $status;
    public $longitude;
    public $latitude;
    public $zone_code;
    public $zone_list = [];
    public $state_model;

    public function __construct(MasterState $state_model = null)
    {
        $this->state_model = Yii::createObject([
            'class' => MasterState::className()
        ]);

        if ($state_model) {
            $this->state_model = $state_model;
            $this->state_code = $state_model->state_code;
            $this->state_name = $state_model->state_name;
            $this->zone_code = $state_model->zone_code;
            $this->longitude = $state_model->longitude;
            $this->latitude = $state_model->latitude;
            $this->status = $state_model->status;
        }

        $this->zone_list = ArrayHelper::map(MasterZone::find()->where(['status' => 1])->all(), 'zone_code', 'zone_name');
    }

    public function rules()
    {
        return [
            [['state_code', 'state_name', 'zone_code'], 'required'],
            [['state_name', 'longitude', 'latitude'], 'string', 'max' => 255],
            [['state_code', 'status', 'zone_code'], 'integer'],
            ['state_code', 'unique', 'targetClass' => MasterState::className(), 'message' => 'This State Code already exists']
        ];
    }

    public function initializeForm()
    {
        $this->state_model->state_code = $this->state_code;
        $this->state_model->state_name = $this->state_name;
        $this->state_model->status = $this->status;
        $this->state_model->zone_code = $this->zone_code;
        $this->state_model->longitude = $this->longitude;
        $this->state_model->latitude = $this->latitude;
    }
}

Step 2: Create a Controller Action

Modify MasterStateController.php to use the Form Model:

namespace app\modules\location\controllers;

use Yii;
use app\modules\location\models\MasterState;
use app\modules\location\models\form\MasterStateForm;
use yii\web\Controller;
use yii\web\NotFoundHttpException;

class MasterStateController extends Controller
{
    public function actionState($state_code = null)
    {
        if ($state_code != null) {
            $state_model = $this->findModel($state_code);
            $model = new MasterStateForm($state_model);
        } else {
            $model = new MasterStateForm();
        }

        if ($this->request->isPost && $model->load($this->request->post()) && $model->validate()) {
            $model->initializeForm();
            if ($model->state_model->save(false)) {
                Yii::$app->session->setFlash('success', 'State Updated Successfully!');
                return $this->redirect(['index']);
            }
        }

        return $this->render('form', [
            'model' => $model,
            'state_model' => $state_model ?? null
        ]);
    }

    protected function findModel($state_code)
    {
        if ($model = MasterState::find()->where(['state_code' => $state_code])->one()) {
            return $model;
        }
        throw new NotFoundHttpException('State not found.');
    }
}

Step 3: Create the Form View

In views/master-state/form.php:

use yii\helpers\Html;
use yii\widgets\ActiveForm;

/* @var $this yii\web\View */
/* @var $model app\modules\location\models\form\MasterStateForm */
/* @var $form yii\widgets\ActiveForm */

?>

<div class="master-state-form">
    <?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'state_name')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'zone_code')->dropDownList($model->zone_list, ['prompt' => 'Select Zone']) ?>
    <?= $form->field($model, 'status')->dropDownList([1 => 'Active', 0 => 'Inactive']) ?>
    
    <div class="form-group">
        <?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
    </div>

    <?php ActiveForm::end(); ?>
</div>

Conclusion

Gii Approach (Default Yii2)

  • Quickly generates CRUD operations.
  • Suitable for basic CRUD applications.

Form Model Approach (Recommended by Dynamic Duniya)

  • Provides more flexibility.
  • Useful for handling custom business logic and validation before saving data.