How To Use A Single Form To Collect Data For The Related Models

First

there has a Tutorials : http://www.yiiframework.com/wiki/19/how-to-use-a-single-form-to-collect-data-for-two-or-more-models/

But,

How to use a few related models to create a related form?

I created an association model, if the corresponding data in the database, the instance when the master model, with the instance of the associated table (model), but no instance in the new data, the associated table (model),an empty array.

If new data can get to the instance of the associated model, then you can use this instance to generate a form, you do not need to instantiate multiple models to generate the form.

the tables:





CREATE TABLE IF NOT EXISTS `categories` (

  `category_id` smallint(6) unsigned NOT NULL AUTO_INCREMENT COMMENT '栏目ID',

  `sort` smallint(6) unsigned NOT NULL DEFAULT '99' COMMENT '排序',

  `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态;1正常;0:禁用',

  `add_time` int(10) unsigned NOT NULL COMMENT '创建时间',

  `update_time` int(10) unsigned NOT NULL COMMENT '更新时间',

  PRIMARY KEY (`category_id`),

  KEY `status` (`status`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='栏目' AUTO_INCREMENT=1 ;


CREATE TABLE IF NOT EXISTS `category_i18ns` (

  `category_id` smallint(6) unsigned NOT NULL COMMENT '栏目ID',

  `language` char(2) NOT NULL COMMENT '语言ISO2',

  `name` varchar(255) NOT NULL COMMENT '名称',

  `seo_title` varchar(255) NOT NULL COMMENT 'SEO标题',

  `seo_keywords` varchar(255) NOT NULL COMMENT 'SEO关键词',

  `seo_description` varchar(255) NOT NULL COMMENT 'SEO描述',

  `update_time` int(10) unsigned NOT NULL COMMENT '更新时间',

  PRIMARY KEY (`category_id`,`language`),

  KEY `language` (`language`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='多语言表';




The demo data




+-------------+------+--------+-----------+-------------+

| category_id | sort | status | add_time  | update_time |

+-------------+------+--------+-----------+-------------+

|           1 |   99 |      1 | 123456790 |   123456790 |

+-------------+------+--------+-----------+-------------+




+-------------+----------+---------------+----------------+---------------+-------------------+-------------+

| category_id | language | name          | seo_title      | seo_keywords  | seo_description   | update_time |

+-------------+----------+---------------+----------------+---------------+-------------------+-------------+

|           1 | cn       | 测试栏目      | 测试seo标题    | 测试seo关键词 | 测试seo描述       |  1234567890 |

|           1 | en       | test category | test seo title | test keywords | test description  |  1234567890 |

+-------------+----------+---------------+----------------+---------------+-------------------+-------------+






The model




class Categories extends CActiveRecord

{

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	public function tableName()

	{

		return 'categories';

	}




	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('add_time, update_time', 'required'),

			array('sort, status', 'numerical', 'integerOnly'=>true),

			array('add_time, update_time', 'length', 'max'=>10),

			// The following rule is used by search().

			// Please remove those attributes that should not be searched.

			array('category_id, sort, status, add_time, update_time', 'safe', 'on'=>'search'),

		);

	}


	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

            //i18n relations

            'i18n'=>array(

                self::HAS_MANY,

                //'joinType'=>'INNER JOIN',

                'CategoryI18ns',

                '',

                'on'=>'t.category_id=i18n.category_id',

                'condition' => 'i18n.language = :language',

                'params' => array(':language'=>'cn')

            ),

		);

	}


	public function attributeLabels()

	{

		return array(

			'category_id' => 'Category',

			'sort' => 'Sort',

			'status' => 'Status',

			'add_time' => 'Add Time',

			'update_time' => 'Update Time',

		);

	}


	public function search()

	{

		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new CDbCriteria;


		$criteria->compare('category_id',$this->category_id);

		$criteria->compare('sort',$this->sort);

		$criteria->compare('status',$this->status);

		$criteria->compare('add_time',$this->add_time,true);

		$criteria->compare('update_time',$this->update_time,true);


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}

}







class CategoryI18ns extends CActiveRecord

{

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	public function tableName()

	{

		return 'category_i18ns';

	}


	public function rules()

	{

		return array(

			array('category_id, language, name, seo_title, seo_keywords, seo_description, update_time', 'required'),

			array('category_id', 'numerical', 'integerOnly'=>true),

			array('language', 'length', 'max'=>2),

			array('name, seo_title, seo_keywords, seo_description', 'length', 'max'=>255),

			array('update_time', 'length', 'max'=>10),

			// The following rule is used by search().

			// Please remove those attributes that should not be searched.

			array('category_id, language, name, seo_title, seo_keywords, seo_description, update_time', 'safe', 'on'=>'search'),

		);

	}




	public function relations()

	{

		return array(


		);

	}


	public function attributeLabels()

	{

		return array(

			'category_id' => 'Category',

			'language' => 'Language',

			'name' => 'Name',

			'seo_title' => 'Seo Title',

			'seo_keywords' => 'Seo Keywords',

			'seo_description' => 'Seo Description',

			'update_time' => 'Update Time',

		);

	}


	public function search()

	{

		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new CDbCriteria;


		$criteria->compare('category_id',$this->category_id);

		$criteria->compare('language',$this->language,true);

		$criteria->compare('name',$this->name,true);

		$criteria->compare('seo_title',$this->seo_title,true);

		$criteria->compare('seo_keywords',$this->seo_keywords,true);

		$criteria->compare('seo_description',$this->seo_description,true);

		$criteria->compare('update_time',$this->update_time,true);


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}

}



in the Controller




class CategoriesController extends Controller

{

	/**

	 * @var string the default layout for the views. Defaults to '//layouts/column2', meaning

	 * using two-column layout. See 'protected/views/layouts/column2.php'.

	 */

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


    public function loadModel($category_id, $language = '')

    {

        //$i18n_relation = empty($language) ? array() : array('params' => array(':language'=>'\'' . $language . '\''));

        $category = Categories::model()->with(array(

            //'i18n' => $i18n_relation,

            'i18n' => array(),

        ))->findByPk($category_id);

        if($category === NULL) throw new CHttpException(404,'The measure does not exist.');

        return $category;

    }


	/**

	 * Displays a particular model.

	 */

	public function actionView()

	{

        $id = intval($_GET['id']);

        $language = addslashes(trim($_GET['language']));

        $category = $this->loadModel($id,$language);

        var_dump($category->i18n[0]->getAttributes());


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

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

		));*/

	}


	/**

	 * Creates a new model.

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

	 */

	public function actionCreate()

	{

		$model=new Categories;

        var_dump($model->i18n);

        exit;

		// Uncomment the following line if AJAX validation is needed

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


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

		{

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

			if($model->save())

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

		}


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

			'model'=>$model,

		));

	}


}



in the view action




var_dump($category->i18n[0]->getAttributes());



return

array (size=7)

‘category_id’ => string ‘1’ (length=1)

‘language’ => string ‘cn’ (length=2)

‘name’ => string ‘测试栏目’ (length=12)

‘seo_title’ => string ‘测试seo标题’ (length=21)

‘seo_keywords’ => string ‘测试seo关键词’ (length=24)

‘seo_description’ => string ‘测试seo描述’ (length=21)

‘update_time’ => string ‘1234567890’ (length=10)

and the


$category->i18n[0]

is an instance from CategoryI18ns model 。

But, in Create action




 $model=new Categories;

 var_dump($model->i18n);



it is an

array (size=0)

empty

How to get the instance from CategoryI18ns model in the create action?

If we get the instance ,we can create an form through just one model which has config relations。

thanks。