Creating a hierachy of model in the controller

I currently have quite a complex object / model hierachy. The system being designed is for Solar Power installers and consists of the following model hierachy:

  • Project has:

[indent]

  • Customer

  • Photovoltaic System has:

    [indent]
    
    
    - Installation Site / Location
    
    
    - Power Inverter
    
    
    - Misc Components
    
    
    - Photovoltaic Arrays has:
    
    
       [indent]
    
    
       - Photovoltaic Modules
    
    
       [/indent]
    
    
    [/indent]
    

[/indent]

The basis of the system is a photovoltaic solar system has multiple arrays which are made up of multiple photovoltaic modules ( solar panels ).

The main user interaction point is going to be based around the Project controller. Where the user goes through a stepped process that creates a project / pv system.

My Question: Is there a better way to init the model inheritance / encapsulation hierarchy described above in the controller then i am currently doing… see below? any tips are welcome. Best Practices is the name of my game. GO YII!

below is code from Project controller


	/**

	 * Creates a new model.

	 * If creation is successful, the browser will be redirected to the 'view' page.

	 */

	public function actionCreate()

	{

		// define and init model hierachy 

		$model = new project;

		$model->customer = new customer;

		$model->system = new system;

		$model->system->site = new site;

		$model->system->site->address = new address;

		$model->system->site->location = new location;

		$model->system->pv_arrays[0] = new pv_array;

		//$model->system->pv_arrays->modules = new component;


		// Uncomment the following line if AJAX validation is needed

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


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

		{ print_r($_POST);exit;

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

			if($model->save())

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

		}


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

			'model'=>$model,

		));

	}

virtually i think there must be a better way of doing things in the view such as:


		<div class="row">

			<?php echo $form->labelEx($model->system->site->address,'state'); ?>

			<?php echo $form->dropDownList($model->system->site->address, 'state', $model->system->site->address->states ); ?>

			<?php echo $form->error($model->system->site->address,'state'); ?>

		</div>	

and the way im doing things in the controller in the above post

bump, no responses yet?

For a project where I had a type » brand » model » vehicle hierarchy, what I did in the vehicle _form.php view:




  <div class="row">


    <?php echo $form->labelEx($model,'vehicleTypeId'); ?>

    <?php echo $form->dropDownList($model,'vehicleTypeId',

                     CHtml::listData(VehicleType::model()->findAll(array('order'=>'id')), 'id', 'vehicleType'),

                     array('empty' => '(Choose a vehicle type)',

                       'ajax' => array('type'=>'GET',

                                 'url'=>CController::createUrl('vehicle/brands'),

                                 'update'=>'#Vehicle_brandId'

                              )

                      )

                     ); ?>

    <?php echo $form->error($model,'vehicleTypeId'); ?>

  </div>


  <div class="row">

    <?php echo $form->labelEx($model,'brandId'); ?>

    <?php

      if(isset($_POST['Vehicle']['brandId']))

        echo CHtml::dropDownList('Vehicle[brandId]', $_POST['Vehicle']['brandId'],

                     CHtml::listData(Brand::model()->findAll(array('condition'=>'vehicleTypeId=:id','params'=>array(':id'=>$_POST['Vehicle']['vehicleTypeId']))), 'id', 'brand'),

                     array('empty' => '(Choose a brand)',

                         'ajax' => array('type'=>'GET',

                                 'url'=>CController::createUrl('vehicle/models'),

                                 'update'=>'#Vehicle_modelId'

                              )

                      )

                    );

      else

        echo CHtml::dropDownList('Vehicle[brandId]', $model->brandId,

                     CHtml::listData(Marque::model()->findAll(array('condition'=>'vehicleTypeId=:id','params'=>array(':id'=>$model->vehicleTypeId))), 'id', 'brand'),

                     array('empty' => '(Choose a brand)',

                         'ajax' => array('type'=>'GET',

                                 'url'=>CController::createUrl('vehicle/models'),

                                 'update'=>'#Vehicle_modelId'

                              )

                      )

                    );

    ?>

    <?php echo $form->error($model,'brandId'); ?>

  </div>


  <div class="row">

    <?php echo $form->labelEx($model,'modelId'); ?>

    <?php

      if(isset($_POST['Vehicle']['modelId']))

        echo CHtml::dropDownList('Vehicle[modelId]', $_POST['Vehicle']['modelId'],

                     CHtml::listData(Model::model()->findAll(array('condition'=>'brandId=:id','params'=>array(':id'=>$_POST['Vehicle']['brandId']))), 'id', 'model'),

                     array('empty' => '(Choose a model)')

                    );

      else

        echo CHtml::dropDownList('Vehicle[modelId]', $model->modelId,

                     CHtml::listData(Model::model()->findAll(array('condition'=>'brandId=:id','params'=>array(':id'=>$model->brandId))), 'id', 'model'),

                     array('empty' => '(Choose a model)')

                    );

    ?>

    <?php echo $form->error($model,'modelId'); ?>

  </div>



and in VehicleController.php




  public function actionCreate()

  {

      $model=new Vehicle;

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

      {

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

        if($model->save()) {

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

        }

      }

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

        'model'=>$model,

      ));

  }


(…)


  public function actionBrands()

  {

    $data=Brand::model()->findAll('typeVehiculeId=:parent_id', 

                    array(':parent_id'=>(int) $_GET['Vehicule']['typeVehiculeId']));

    $data=CHtml::listData($data,'id','brand');

    if(count($data) > 0) {

      echo CHtml::tag('option',

              array('value'=>''),

              CHtml::encode('(Choose a brand)'),

              true);

      foreach($data as $value=>$name)

        echo CHtml::tag('option',

                array('value'=>$value),

                CHtml::encode($name),

                true);

    } else

      echo CHtml::tag('option',

              array('value'=>''),

              CHtml::encode('(Choose a vehicle type first)'),

              true);

  }


  public function actionModels()

  {

    $data=Model::model()->findAll('brandId=:parent_id', 

                    array(':parent_id'=>(int) $_GET['Vehicule']['brandId']));

    $data=CHtml::listData($data,'id','model');

    if(count($data) > 0) {

      echo CHtml::tag('option',

              array('value'=>''),

              CHtml::encode('(Choose a model)'),

              true);

      foreach($data as $value=>$name)

        echo CHtml::tag('option',

                array('value'=>$value),

                CHtml::encode($name),

                true);

    } else

      echo CHtml::tag('option',

              array('value'=>''),

              CHtml::encode('(Choose a brand first)'),

              true);

  }