goose
goose

Reputation: 2652

Yii - multiple records in one form submission

Does anyone know how to add multiple records using just one form in Yii? All the records belong to the same model and are of the same format.

Many thanks,

Nick

Upvotes: 6

Views: 14880

Answers (2)

Nabi K.A.Z.
Nabi K.A.Z.

Reputation: 10714

Put this code in components folder under GeneralRepository.php file name.

<?php
class GeneralRepository
{
    /**
     * Creates and executes an INSERT SQL statement for several rows.
     * 
     * Usage:
     * $rows = array(
     *      array('id' => 1, 'name' => 'John'),
     *      array('id' => 2, 'name' => 'Mark')
     * );
     * GeneralRepository::insertSeveral(User::model()->tableName(), $rows);
     * 
     * @param string $table the table that new rows will be inserted into.
     * @param array $array_columns the array of column datas array(array(name=>value,...),...) to be inserted into the table.
     * @return integer number of rows affected by the execution.
     */
    public static function insertSeveral($table, $array_columns)
    {
        $connection = Yii::app()->db;
        $sql = '';
        $params = array();
        $i = 0;
        foreach ($array_columns as $columns) {
            $names = array();
            $placeholders = array();
            foreach ($columns as $name => $value) {
                if (!$i) {
                    $names[] = $connection->quoteColumnName($name);
                }
                if ($value instanceof CDbExpression) {
                    $placeholders[] = $value->expression;
                    foreach ($value->params as $n => $v)
                        $params[$n] = $v;
                } else {
                    $placeholders[] = ':' . $name . $i;
                    $params[':' . $name . $i] = $value;
                }
            }
            if (!$i) {
                $sql = 'INSERT INTO ' . $connection->quoteTableName($table)
                . ' (' . implode(', ', $names) . ') VALUES ('
                . implode(', ', $placeholders) . ')';
            } else {
                $sql .= ',(' . implode(', ', $placeholders) . ')';
            }
            $i++;
        }
        $command = Yii::app()->db->createCommand($sql);
        return $command->execute($params);
    }
}

And usage anywhere:

$rows = array(
    array('id' => 1, 'name' => 'John'),
    array('id' => 2, 'name' => 'Mark')
);
GeneralRepository::insertSeveral(User::model()->tableName(), $rows);

This just execute one query.

Upvotes: 0

bool.dev
bool.dev

Reputation: 17478

The equivalent "batchCreate" method of the "batchUpdate" from the guide could be something like this:

public function actionBatchCreate() {
    $models=array();
    // since you know how many models
    $i=0;
    while($i<5) {
        $models[]=Modelname::model();
        // you can also allocate memory for the model with `new Modelname` instead
        // of assigning the static model
    }
    if (isset($_POST['Modelname'])) {
        $valid=true;
        foreach ($_POST['Modelname'] as $j=>$model) {
            if (isset($_POST['Modelname'][$j])) {
                $models[$j]=new Modelname; // if you had static model only
                $models[$j]->attributes=$model;
                $valid=$models[$j]->validate() && $valid;
            }
        }
        if ($valid) {
            $i=0;
            while (isset($models[$i])) {
                $models[$i++]->save(false);// models have already been validated
            }
            // anything else that you want to do, for example a redirect to admin page
            $this->redirect(array('modelname/admin'));
        }
    }

    $this->render('batch-create-form',array('models'=>$models));
}

The only concern here is that a new instance has to be created for each model that you are saving, using new. The rest of the logic can be implemented in any way you wish, for example in the above example all the models are being validated, and then saved, whereas you could have stopped validation if any model was invalid, or maybe directly saved the models, letting validation happen during save call. So the logic will really depend on your app's ux.

Upvotes: 9

Related Questions