looking for alternative (more elegant) solution to create related records

I have a user table with primary key id, i have a profile table that is related to the user table where 1 user has one profile. the foreign key in the profile table for the user-profile relationship is userId.

when a user record is created, i also want a related profile record to be created.

currently this is the solution i have


	public function actionRegister()

	{

		$user    = new User;

		$profile = new Profile;

		

		if(isset($_POST['User'], $_POST['Profile']))

		{

			$user->attributes    = $_POST['User'];

			$profile->attributes = $_POST['Profile'];

			if($user->save())

			{

				// assigns the id of the user record to userId of profile object

				$profile->userId = $user->id;

				if($profile->save())

				{

					// both user and profile records were saved, redirect to login page

					$this->redirect(array(Yii::app()->user->loginUrl);

				}else{

					// deletes user record if profile record was not saved.

					$user->delete();

				}

			}

		}

		

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

			'user'=>$user,

			'profile'=>$profile

		));

	}

The problem with this is that if a user record is created but there is a validation error in one of the profile fields, then $user->delete(); will be called then the form is rendered and shows the validation errors, but the id field will be incremented in the user table. If the user submits the form 10 times with error in a profile field then the id will be incremented 10 times so if the last good registration got an id of one, the new one will get an id of 21. Does any 1 have a better solution?

so far this seems to be a better solution.


	public function actionRegister()

	{

		$user           = new User;

		$profile        = new Profile;

		$user->scenario = 'register';

		if(isset($_POST['User'], $_POST['Profile']))

		{

			$transaction         = $user->dbConnection->beginTransaction();

			$user->attributes    = $_POST['User'];

			$profile->attributes = $_POST['Profile'];

			if(!$profile->hasErrors())

			{

				if($user->save())

				{

					$profile->userId = $user->id;

					if($profile->save())

					{

						$transaction->commit();

						$this->redirect(Yii::app()->user->loginUrl);

					}else{

						$transaction->rollBack();

					}

				}

			}

		}

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

			'user'=>$user,

			'profile'=>$profile

		));

	}

anyone has something better?

You could put the logic of profile creation/update into before/afterSave() of User as the relation between User - Profile is part of your models. Fat models and thin controllers are a good thing ;).

You could also split the process in 2 step-by-step pages. First for saving the user with it’s data and, once validated and saved, the visitors gets redirected to the second page where the profile form is presented.