Error 404 On View After Create

Hi:

I have a model based on a MySQL updateable view in a multitenant SaaS application. The MySQL view is almost identical to the underlying table, the difference being it doesn’t have the MySQL username column the table has; it contains all other columns so it’s updateable and the missing column is handled by a trigger on insert and a where clause on retrieve.

The model is as follows:




class VVehicle extends CActiveRecord

{

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	public function tableName()

	{

		return 'vw_vehicle'; // a MySQL view, not a table

	}

	

	public function primaryKey()

	{

		return 'id'; // same as underlying table PK (int, autoincrement, etc.)

	}

	/**

	 * @return array validation rules for model attributes.

	 */

...



The controller’s class is pretty standard:




class VVehicleController extends Controller

{

	public $layout='//layouts/column2';


...


	public function actionView($id)

	{

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

			'model'=>$this->loadModel($id),

		));

	}

	

	public function actionCreate()

	{

		$model=new VVehicle;


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


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

		{

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

			if($model->save())

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

		}


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

			'model'=>$model,

		));

	}


...


	public function loadModel($id)

	{

		$model=VVehicle::model()->findByPk($id);

		if($model===null)

			throw new CHttpException(404,'The requested page does not exist.');

		return $model;

	}


...

}



I can create a new record just fine, but when the controller redirects to view.php to display it I get an error "404 - The requested page does not exist." which I believe comes from loadModel($id).

The browser shows an incomplete URL:




http://mydomain.com/index.php?r=vVehicle/view&id=



Not having the record id causes the action to fail. I don’t understand why it isn’t being passed from the if ($model->save()) statement to the redirect right after it. As I explained, the data is saved without any issues and if I provide the id, the view.php works fine.

Any ideas? Thanks for the help.

you can load new inserted id by use


$model->primaryKey; 						 						

So you can try this :


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

                {

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

                        if($model->save())

$id=$model->primaryKey;                               

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

                }



Thanks, but unfortunately it didn’t work. I even tried adding $model->refresh() before setting the $id. I reckon that the reason is that the model is null because that’s the condition in the loadModel($id) function. I don’t understand how it can be nulled after the save().

Any more ideas are greatly appreciated.

You’ll need to debug it a step at a time.

Start by outputting the newly assigned id after the creation request rather than redirecting. If the id attribute doesn’t have a value then it suggests something is wrong with how your database table or model is configured.

Try replacing




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

                {

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

                        if($model->save())

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

                }



with




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

                {

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

                        if($model->save())

                        {

                                print_r($model->attributes);

                                Yii::app()->end();

                        }

                }



Post the results here.

$model null how ?! please try this code and let me know result





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

                {

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

                        if($model->save()){

if($model===null){

echo " It's null ";

}

else{

 $id=$model->primaryKey;                               

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


}


}

                }

I just tried it. It didn’t echo “It’s null” so it probably isn’t, but I still got the 404 error so something’s wrong.

I am on to something. I found this forum post Active Record with PostgreSQL view that kind of explains what’s going on. It seems that Yii not only doesn’t recognize a primary key in a database view, but it also doesn’t recognize its sequenceName (e.g. LAST_INSERT_ID). Now I need to find how it’s called in MySQL. Any ideas are welcome…

I kept digging and it seems that I solved the problem with this addition to the model:




/**

 * Overriden method with updates required after saving to table.

 */

public function afterSave()

{

	if ($this->getIsNewRecord())

	{

		$this->id = Yii::app()->db->getLastInsertID();

	}

		

	return parent::afterSave();

}



However, I don’t know enough about Yii to tell if this is multiuser safe, as the call is to the database in general and not specific to a table. What if there are other users creating either similar or other records simultaneously? Please let me know, thanks.

It only applies to the current connection, so it will work correctly for each request.

More info here.

Thanks for the quick reply, I just learned it right now while reading the MySQL documentation. Cheers!