Update multiple records from form via POST

Using the Collecting Tabular Input example in the Guide, I want to update multiple records in a model, but update is not working.

The validation in the controller is failing. If I do a var_dump of $items, i am seeing the id, startime and stoptime passed, but the id is a string. Maybe this is what is causing the validation to fail?

e.g.

array (size=7)

0 =>

array (size=3)


  'id' => string '8' (length=1)


  'starttime' => string '11:00' (length=5)


  'endtime' =&gt; string '22:00:00' (length=<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' />

Here is the code in my View




        <h3> Login Schedule for <?php echo $firstname;?> </h3>

        <div class="form">

        <?php echo CHtml::beginForm(); ?>

        <table>

          <tr><th>Day</th><th>Start Time</th><th>EndTime</th></tr>

          <?php  if(isset($items)) {

                foreach($items as $i=>$item):

                        echo'<tr>

                        <td>'.$items[$i]["dayofweek"].'</td>

                        '.CHtml::activehiddenField($item,"[$i]id", array("value" => intval($item->id))).'

                        <td>'.CHtml::activeTimeField($item,"[$i]starttime").' </td>

                        <td>'.CHtml::activeTimeField($item,"[$i]endtime").' </td>

                        </tr>';

                endforeach;

                } else {

                        echo'<tr><td>Schedule Not Found </td></tr>';

                } ?>

        </table>


        <?php echo CHtml::submitButton('Save'); ?>

        <?php echo CHtml::endForm(); ?>

        </div><!-- form -->



And here is the Controller code.




// Update Schedule      //


public function actionupdateSchedule()

        {

        // retrieve items to be updated in a batch mode

        $sql = "select si.id, dayofweek, starttime, endtime from ScheduleItems si

	inner join Schedule s  on s.id = si.scheduleId

	inner join User u      on u.loginScheduleId = s.Id

	where u.id =".$userId;


//+----+-----------+-----------+----------+

//| id | dayofweek | starttime | endtime  |

//+----+-----------+-----------+----------+

//|  1 | Monday    | 00:00:00  | 23:59:00 |

//|  2 | Tuesday   | 00:00:00  | 23:59:00 |

//|  3 | Wednesday | 00:00:00  | 23:59:00 |

//|  4 | Thursday  | 00:00:00  | 23:59:00 |

//|  5 | Friday    | 00:00:00  | 23:59:00 |

//|  6 | Saturday  | 00:00:00  | 23:59:00 |

//|  7 | Sunday    | 00:00:00  | 23:59:00 |

//+----+-----------+-----------+----------+


        $items = ScheduleItems::model()->findAllBySql($sql,array('index'=>'id'));


        if(isset($_POST['ScheduleItems']))

        {

            $valid=true;

            foreach($items as $i=>$item)

            {

                if(isset($_POST['ScheduleItems'][$i]))

                    $item->attributes=$_POST['ScheduleItems'][$i];

                    $valid=$item->validate() && $valid;

            }

            if($valid) {  // all items are valid

                // ...do something here

                $i=0;

		while (isset($items[$i])) {

		  $items[$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('manage/index'));

            }

        }

        

        // displays the view to collect tabular input

        // Render Results

        $this->render('updateSchedule',array(

                  'items'=>$items,

                  'firstname'=>$firstname,

                  'userId'=>$userId,

                  ));

        }



What are the errors in the model when it fails to validate?

Also, if you want both of the lines in the if statement here, you need to add braces:




                if(isset($_POST['ScheduleItems'][$i]))

                    $item->attributes=$_POST['ScheduleItems'][$i];

                    $valid=$item->validate() && $valid; // <- I'm not in the if statement body



For testing, I would probably do something as simple as this to find out why validation is failing:




if (isset($_POST['ScheduleItems'][$i]))

{

    $item->attributes = $_POST['ScheduleItems'][$i];


    if (!$item->validate) // Temporary block to see what's going wrong

    {

        var_dump($item->errors);

        die;

    }

}



Great advice! Thanks. I have this working now.

The missing braces are also missing in the example in the Guide. see Collecting Tabular Input

The Error was:


array (size=1)

  'scheduleId' => 

    array (size=1)

      0 => string 'Schedule cannot be blank.' (length=25)

scheduleId is a NOT NULL field in the ScheduleItems model. I needed to include scheduleId in the SQL select statement. I would have thought that Yii would only need the id (Primary Key) and changed fields on an existing entry, but apparently this is not the case.

So final (working) Controller looks like this:


public function actionupdateSchedule()

    {

        $userId = Yii::app()->user->userId;

        $firstname = Yii::app()->user->firstname;


	$sql = "select si.id, scheduleId, dayofweek, starttime, endtime from ScheduleItems si

	inner join Schedule s  on s.id = si.scheduleId

	inner join User u      on u.loginScheduleId = s.Id

	where u.id =".$userId;


	$items = ScheduleItems::model()->findAllBySql($sql,array('index'=>'id'));


        if(isset($_POST['ScheduleItems']))

        {

            $valid=true;

            foreach($items as $i=>$item)

            {

                if (isset($_POST['ScheduleItems'][$i]))

                {

                    $item->attributes = $_POST['ScheduleItems'][$i];

                    $valid=$item->validate() && $valid;

                }

                if($valid) {  // all items are valid so save them.

                    $i=0;

                    while (isset($items[$i])) {

                        $items[$i++]->save(false); // items have already been validated

                        }

                }

            }

            $this->redirect(array('manage/index'));

	}


        // displays the view to collect tabular input

        $this->render('updateSchedule',array(

          'items'=>$items,

          'firstname'=>$firstname,

          'userId'=>$userId,

          ));

    }