Yii Framework Forum: Need help with related tabular input - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Need help with related tabular input Rate Topic: ****- 1 Votes

#1 User is offline   waitforit 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 346
  • Joined: 09-February 11

Posted 16 August 2011 - 07:49 AM

I have two tables with a one-to-many relationship.

The related table has a tabular input form to collect multiple instances.

The problem I'm having is this:

If I omit any required fields from my primary table, I get an error message - this is good.
If I omit any required fields from the dependent table, it saves the primary and redirects. Not good.

I've read the wiki and forum about multimodel forms but this doesn't really apply to my situation. The problem is that I need to make sure that both the primary and related table have $_POST data and if not, show the required error.

How do you do multiple model forms with tabular input?

I've tried to change this code to use the $valid=$model->validate() && $valid workflow suggested in the wiki - but the problem is that I don't know how to make this work in a 1:Many situation.

My code:
	if(isset($_POST['Inspection'])) {
		//Manually assign model attributes since not coming from user form. Skipping massive assignment
		$model->attributes=$_POST['Inspection'];
		$model->userId=Yii::App()->user->id;
		$model->assignmentId=$assignment->id;
		$model->status=1;
		if($model->save()) {
			if(isset($_POST['InspectionData'])) {
			//Need to handle if relatedData NOT posted as only parent model will be saved and will not see validation errors.
				foreach ($_POST['InspectionData'] as $i=>$insData) {
					//Foreach Inspection saved, load inspectionData model
					//and assign form fields
					$InspectionData = new InspectionData;
					$InspectionData->inspectionId = $model->id;
					$InspectionData->criteriaName = $criteria[$i]; //Criteria is not coming from user input but from the query
					$InspectionData->compliant = $insData['compliant'];
					$InspectionData->notes = $insData['notes'];
					$InspectionData->save();
				}
			}
			//Set create flash message and send user to dashboard? page (change to Inspection History when built)
			Yii::app()->user->setFlash('create', 'Inspection recorded successfully.');
				$this->redirect(array('/dashboard'));
		}
	}

0

#2 User is offline   Dana 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 199
  • Joined: 18-February 10
  • Location:Florida, USA

Posted 16 August 2011 - 09:40 AM

You should change your logic so that you're doing something like:
(The kicker will be that you can't validate for the ID of the Inspection on the children)
if (isset( $_POST['Inspection'] )
{
   $model->attributes=$_POST['Inspection'];
   $model->userId=Yii::App()->user->id;
   $model->assignmentId=$assignment->id;
   $model->status=1;
   if ( $model->validate() )
   {
      $foundInvalidChild = false;
      $arrInspectionData = array();
      if ( isset( $_POST['InspectionData'] ) )
      {
          foreach ($_POST['InspectionData'] as $i=>$insData) {
             //Foreach Inspection saved, load inspectionData model
             //and assign form fields
             $InspectionData = new InspectionData;
             // massively assign the data posted
             $InspectionData->attributes = $insData;
             // we can only do this if the parent has been saved ... 
             if ( $model->id )
               $InspectionData->inspectionId = $model->id;
             $InspectionData->criteriaName = $criteria[$i]; //Criteria is not coming from user input but from the query

            // These should be massively assigned
            // $InspectionData->compliant = $insData['compliant'];
            // $InspectionData->notes = $insData['notes'];
            
             if ( ! $InspectionData->validate() )
                $foundInvalidChild = true;

             $arrInspectionData[] = $InspectionData;
         }

      }
      if ( !$foundInvalidChild && $model->save() ) 
      { 
           foreach( $arrInspectionData as $InspectionData )
           {
              $InspectionData->inspectionId = $model->id;
              $InspectionData->save();
           }
           // do the rest of your post-save stuff here.
      }
   }
   // do your draw form here
}

0

#3 User is offline   waitforit 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 346
  • Joined: 09-February 11

Posted 16 August 2011 - 10:22 AM

Brilliant!

I think your kicker comment will not be an issue because there is only one parent per form submitted. I have to think about this a little more - I'm not sure I entirely understand what you mean. The InspectionData table has an autoincrement primary ID and a FK to Inspection.

I had a similar situation in another area of my app using a many:many relationship but since I didn't REQUIRE the children to be assigned it wasn't an issue. Thanks for the help!!!
0

#4 User is offline   Dana 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 199
  • Joined: 18-February 10
  • Location:Florida, USA

Posted 16 August 2011 - 10:24 AM

Just make sure that in your validation rules for the InspectionData that inspectionId isn't required and you should be good to go, as far as that "kicker" goes ;)

Because, the model->id isn't set until after it saves, so when you first loop, it would be null.
0

#5 User is offline   waitforit 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 346
  • Joined: 09-February 11

Posted 16 August 2011 - 04:46 PM

One more thing.

In my _form.php I'm using a CActiveForm with this line to display error summary:

<?php echo $form->errorSummary(array($model,$data)); ?>


In order to display the 'child' errors do I need to use AddError?
0

#6 User is offline   waitforit 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 346
  • Joined: 09-February 11

Posted 16 August 2011 - 05:44 PM

I shouldn't work on code late in the today. Please disregard - I just need to use the same model that I am passing to my view. You'll see I am using $data in one place and $InspectionData in another.
0

#7 User is offline   salex 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 17-June 12

Posted 03 October 2012 - 09:37 PM

Cool...something I was looking for recently...
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users