How To Find The Next Primary Key Before $Model Save?

Hi

I have a form which references multiple models, and in my controller I have a requirement to pass my $model->id to the referenced tables before i actually save my $model.

The reason for this is that I take the ID’s in my referenced tables and then pass them into my main $model when saving.

Is there a way to find the ‘next auto incrementing primary key’ value before I save my model?

The following is taken from my controller create.




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

{	 

		$model->attributes=$_POST['Venue'];

		$modelBilling->attributes=$_POST['Billing'];

		$modelGeo->attributes=$_POST['VenueGeo'];


		//validation check

		$valid  =   $model->validate(); 

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

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




		if($valid)

				{

				   // Billing

				   $modelBilling->chain_pays_billing=$model->venue_chain_pays_billing;

				   $modelBilling->save(); // save billing

				   

				   // VenueGeo

				   $modelGeo->venue_id=$model->id; // pass the venue id ****

				   $modelGeo->save(); // save geo location


				   // RegionVenues

				   $modelRegion->venue_id=$model->id; // pass the venue id ****

				   $modelRegion->region_id=$model->region_venues_id; 

				   $modelRegion->region_id1=$model->region_venues_id;

				   $modelRegion->save(); // save selected region venues


				   // if venue is part of a chain populate the chainVenues table

				   $x=$model->venue_part_of_chain; // load up the form value 'yes' or 'no'

				   if($x=='yes') 

					   {

					   		$modelChainVenue->venue_id=$model->id; // pass the venue id ****

					   		$modelChainVenue->chain_id=$model->chain_id;

					   		$modelChainVenue->chain_id1=$model->chain_id;

					   		$modelChainVenue->save(); // save the ChainVenues

					   }


				   // VenueActiveSeason

				   $modelActiveSeason->venue_id=$model->id; // pass the venue id ****

				      $y=Yii::app()->db->getLastInsertId('LeagueActiveSeason'); // get the last inserted id

				   $modelActiveSeason->league_season_id=$y; // pass active season id

				   $modelActiveSeason->league_last_update_id=$y; // pass active season id

				   $modelActiveSeason->league_active_season_id=$y; // pass active season FK_id

				   $modelActiveSeason->save(); // save active season




				   // Venue ****

				   $model->billing_id1=$modelBilling->id; // get the billing ID and assign it to the FK_id

				   $model->venue_geo_id=$modelGeo->id; // pass the geo id to venue geo id

				   $model->chain_venues_id=$modelChainVenue->id; // pass ChainVenue id to venue chain_venues_id

				   $model->venue_active_season_id=$modelActiveSeason->id; // pass the active season id

				   $model->region_venues_id=$modelRegion->id; // pass the region id						   				   

				   $model->save(); // save venue

				   

				   $this->redirect(array('view','id'=>$model->id));

				}

}



The create functionality works, and is writing to the database tables apart from the ‘=$model->id;’ elements before I save the $model

Any help would be most appreciated

GPM

Hi,

To my knowledge, you will not get new id without saving model. Thats why its empty.

What is the purpose of saving $model as last. try as first one.

Thanks

chandran nepolean

Hi Chandran

Thank you for your reply.

The reason I save it last is because I need to gather all the related model ID’s first so that I can use them in my main model.

If there is no way then I guess that I will need to look at my database structure and maybe create a few new extra tables to hold the relational data

GPM

Hi,

If you want to find latest id then find max(id).it will return latest one. Then u do plus one.that is ur id :)

Thanks

chandran nepolean

Oh, disregard this at all costs! What you really want to do is use transactions. They also work with ARs. See here for an example.

You should not try to predict an auto incrementing primary key value. I can give an example from PostgreSQL. It uses sequences as a default value for the primary key. So when executing an INSERT statement you don’t specify the id and PostgreSQL fetches the next sequence number as the default value.

The problem is that sequences are the only thing in PostgreSQL that is always common to all transaction. That is, if you begin one transaction and fetch the next value from a sequence, in all other transactions you will never fetch the same value. If you do a rollback and then try it again, you will get a different (next) value.

In a short time between fetching the next value and saving the record some other request may insert a record with this value and you will get an unique key violation exception. You should handle it properly, that is try the whole operation again or avoid it at all.

Maybe just reading the id AFTER saving and saving other related objects in right order would be simpler and less error prone. Your call.

Thank you to everyone who has taken the time to respond to my question.

I have now introduced transactions into my model as that is something which has great benefits.

Regarding predicting the next primary key, I understand now that this is a design mistake on my part with my model and database, both of which I am reviewing at the moment to find a much cleaner solution.

Once again many thanks

GPM