Calc And Validate Many Relative Tabular Input Fields

Hello!

There is a form, that contains many (>100) relative fields (models Document, Field, Value).

Some of them has to be summed up, multiplied. Results have to be compared to each other…

Question is how and where (in controller or model) would be right to implement the math and it’s validation?

Below i’ve described model and both possible solution, but there are major disadvantage in each one.

[size="5"]1st: Controller[/size]

If solution will be implemented in controller, all math should and data’s save logic should be written in it… But, in this case, the new questions appear, if we want to process our data somewhere else

[size=“1”]Getting of the data and it’s independent validation is made as “Collecting Tabular Input” article (http://www.yiiframework.com/doc/guide/1.1/en/form.table)[/size]




class DocumentController extends Controller{

  public function actionUpdate() {


    /** Getting already saved data */

    $values = $document->values;


   /** Going over every field and create models for a values*/

    foreach ($allFields as $fieldId) {

      if (!$values[$fieldId]) {

        $value = new Value();

        $value->documentId = $document->id;

        $value->fieldId = $fieldId;

        $values[$fieldId] = $value;

      }


    /** Is Form submitted? */

    if (isset($_POST['Document'])) {

      /** Checking values */

      $valuesValid = true;

      foreach ($values as $i => $value) {

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

          $value->attributes = $_POST['Document'][$i];

        $valuesValid = $value->validate() && $valuesValid;

      }


      if ($valuesValid) {

        /** Do and validate the math  */

       $allOk = true || false;

      }


      /** Saving if all's ok */

      if ($allOk) {

        foreach ($values as $value) {

          $value->save(false); 

        }

       $this->redirect('somewhere');

      }




    /** Render */

    $this->render('view' array(

      'document' => $document,

      'values' => $values,

      'fields' => $fields,

    ));


  }

}

 

[size="6"]2nd: Model[/size]

If math is implemented in model, there is a problem: we can’t work with $document->fields: it doesn’t exist before save, and this field is read-only. That’s why we should make a fuss wigh extra field:




class Document extends CActiveRecord{

  public $tempFields;


/**

  * Math and validation by this extra field $tempFields

  * @return boolean  */

  public function calc(){ }


/** saving values */

  public function Document::saveData(),

}



In controller we should:

  1. get all data and validate each field

  2. assign data to $document->tempFields

  3. call $document->calc(), which will do the math and raise errors

  4. if all’s fine, call $document->saveFields(),

Finally, controller’s code won’t get less, and what should we do if we need to change the data.

It will be already in $document->field, but math is tied on $document->tempFields.

Should we assign all values to temp ones? Pass as parameters to math function?