Sunday, January 12, 2014

Cascade create a model and attach it to another model in Controller in a One-to-Many relationship (Yii)

Suppose we have a situation where we a set of users, each of which belong to a particular project. In Yii, we already create two models, namely Project and User. The User model class contains an attribute project_id, which is the id attribute value of the associated Project model. Now a user cannot be created without knowing the project_id it is associated with

Step 1:

In the protected/views/project/view.php, add a link to create user associated with the project:

<?php echo CHtml::link(CHtml::encode('Create user under the project'), array('user/create', 'project_id'=>$model->id)); ?>
The project_id allows the UserController (i.e. the controller associated with the User model) to identify the project_id to which the created user should be associated with.

Step 2:

In the protected/controllers/UserController.php, add a private member variable _project:

private $_project = null;

Next in the UserController.php, find the method filters(), and add one line for projectContext filter:

 * @return array action filters
public function filters()
 return array(
  'accessControl', // perform access control for CRUD operations
  'projectContext + create index admin', //check to ensure valid event context

Next in the UserController.php, defines the following methods:

public function filterProjectContext($filterChain) 
 //set the project identifier based on either the GET or POST input
 //request variables, since we allow both types for our actions 
 $project_id = null;
  $project_id = $_GET['project_id'];
   $project_id = $_POST['project_id'];
 //complete the running of other filters and execute the requested action

protected function loadProject($project_id) 
 //if the project property is null, create it based on input id 
   throw new CHttpException(404,'The requested project does not exist.'); 
 return $this->_project;
The above method allows Yii code to create and assign the _project with the content from database using the project_id passed in from Step 1. As a result, before the actionCreate() method is invoked, the _project is already properly initialized based project_id attribute passed in. The final step is to assign $user->project_id in the actionCreate() method of the UserController class, as shown below:
public function actionCreate()
 $model=new User;

 // Uncomment the following line if AJAX validation is needed
 // $this->performAjaxValidation($model);



No comments:

Post a Comment