Save Data With Two Models And One View Form

hi,i’m new to yii…

i find this framework is very convenient for developing a large product …so i choose this…now i have one problem…

I have two table and two table having two models …how i save data with two models using one view form …below is my table structure …plz help me out…it’s very usefull for me…

table 1

pk_id | item_expi_date | item_enable

1 | 0days | true

2 | 10days | true

table 2

fk_id | item_name |item_description

1 | item1 | xxxxxxxxx

2 | item2 | yyyyyyyyy

i create two models using gii… Table1 having primarykey field ,field name is pk_id ,Table2 having foreign key id field name is fk_id…if i insert data using these two tables my Table1 primarykey is referenced foreign key for table2 so i save data using these two models…my view may be only having these two fields item_name and item_descripton only i get user input field from user…

hi, I assuming u already created models of both tables, Now,

In your view file you can simply you can post value  according your models like.....




	<div class="f">	

	<?php echo $form->labelEx($model1,'item_expi_date',array('class'=>'l')); ?>

	<div class="">

  		  <?php echo $form->textField($model1,'item_expi_date',array('maxlength'=>255,'class'=>'form-control','placeholder'=>'Enter first name','title'=>'Please provide your first name')); ?>

		<?php echo $form->error($model1,'item_expi_date'); ?>  

	</div>

	

	</div>

   

  <div class="">

	<?php echo $form->labelEx($model2,'item_name',array('class'=>'')); ?>

	<div class="">  	

	  <?php echo $form->textField($model2,'item_name',array('maxlength'=>255,'class'=>'form-control','placeholder'=>'Enter last name','title'=>'Please provide your last name also')); ?>

	<?php echo $form->error($model2,'item_name'); ?>

	</div>

	

	</div>



SUPPOSE IN your controller function the code is like…




public function actionAction_Name()

{

  $model1 = new Model_of_First_table();

$model2 = new Model_of_second_table();

if(isset($_POST['Model_of_First_table']),$_POST['Model_of_Second_table']) )

{

  	$model1->attributes = $_POST['Model_of_First_table'];

  	$model1->attributes = $_POST['Model_of_Second_table'];

 $model1->save();

$model2->save();





}


}



I hope this will help u

Maybe this will help you link1 and link2

i followed your answer but i didn’t get any error messages at the same the data won’t save in db also…so plz help me i attached my model file and view screenshot also plz help me…

You have a bunch of required attributes for TCategory. Since I don’t see anything like a beforeValidate() method in that model, are you setting all those attributes properly in your controller before calling save?

how i write the before validate method for my model …please help me write the method…

I have two tables with two models and I can successfully save the data into two tables from one form by using afterSave(). Just add this function into models file of your form.

Here’s my working code:




public function afterSave() {

        if($this->isNewRecord){

            $model2 = new CourseTimetable();  //the second model

	    $model2->code = $this->code;      

            $model2->name = $this->name;

			

            $model2->save(false);  //set to false to skip the validation

        }

    }



As simple as this. You can save data into two tables at the same time from one form. Hope that this can help you.

hi this is my code please help to save data …





--

-- Table structure for table


 `t_category`

--


CREATE TABLE IF NOT EXISTS `t_category` (

  `pk_i_id` int(10) unsigned NOT NULL AUTO_INCREMENT,

  

`fk_i_parent_id` int(10) unsigned DEFAULT NULL,

  `i_expiration_days` int(3) unsigned NOT NULL DEFAULT '0',

  

`i_position` int(2) unsigned NOT NULL DEFAULT '0',

  `b_enabled` tinyint(1) NOT NULL DEFAULT '1',

 

 `b_price_enabled` tinyint(1) NOT NULL DEFAULT '1',

  `s_icon` varchar(250) DEFAULT NULL,

  PRIMARY KEY (`pk_i_id`),

 

 KEY `fk_i_parent_id` (`fk_i_parent_id`),

  KEY `i_position` (`i_position`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;







-- Table structure for table `t_category_description`

--


CREATE TABLE IF NOT EXISTS `t_category_description` (

  `fk_i_category_id` int(10) unsigned NOT NULL,

  `fk_c_locale_code` char(5) NOT NULL,

  `s_name` varchar(100) DEFAULT NULL,

  `s_description` text,

  `s_slug` varchar(100) NOT NULL,

  PRIMARY KEY (`fk_i_category_id`,`fk_c_locale_code`),

  KEY `idx_s_slug` (`s_slug`),

  KEY `fk_c_locale_code` (`fk_c_locale_code`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;




-- Table structure for table `t_category_stats`


CREATE TABLE IF NOT EXISTS `t_category_stats` (

  `fk_i_category_id` int(10) unsigned NOT NULL,

  `i_num_items` int(10) unsigned NOT NULL DEFAULT '0',

  PRIMARY KEY (`fk_i_category_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;




--

-- Constraints for dumped tables

--


--

-- Constraints for table `t_category`

--

ALTER TABLE `t_category`

  ADD CONSTRAINT `t_category_ibfk_1` FOREIGN KEY (`fk_i_parent_id`) REFERENCES `t_category` (`pk_i_id`);


--

-- Constraints for table `t_category_description`

--

ALTER TABLE `t_category_description`

  ADD CONSTRAINT `t_category_description_ibfk_1` FOREIGN KEY (`fk_i_category_id`) REFERENCES `t_category` (`pk_i_id`),

  ADD CONSTRAINT `t_category_description_ibfk_2` FOREIGN KEY (`fk_c_locale_code`) REFERENCES `t_locale` (`pk_c_code`);


--

-- Constraints for table `t_category_stats`

--

ALTER TABLE `t_category_stats`

  ADD CONSTRAINT `t_category_stats_ibfk_1` FOREIGN KEY (`fk_i_category_id`) REFERENCES `t_category` (`pk_i_id`);






Below is my controller code …TCategory Controller




<?php


/**

 * This is the model class for table "t_category".

 *

 * The followings are the available columns in table 't_category':

 * @property string $pk_i_id

 * @property string $fk_i_parent_id

 * @property string $i_expiration_days

 * @property string $i_position

 * @property integer $b_enabled

 * @property integer $b_price_enabled

 * @property string $s_icon

 *

 * The followings are the available model relations:

 * @property TCategory $fkIParent

 * @property TCategory[] $tCategories

 * @property TLocale[] $tLocales

 * @property TCategoryStats $tCategoryStats

 * @property TItem[] $tItems

 * @property TKeywords[] $tKeywords

 * @property TMetaFields[] $tMetaFields

 * @property TPluginCategory[] $tPluginCategories

 */

class TCategory extends CActiveRecord

{

	/**

	 * @return string the associated database table name

	 */

    

    

	public function tableName()

	{

		return 't_category';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

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

		// will receive user inputs.

		return array(

                        array('pk_i_id,i_expiration_days,b_enabled,b_price_enabled','required','on'=>'create'),

			array('b_enabled, b_price_enabled,i_expiration_days', 'numerical', 'integerOnly'=>true),

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

			array('i_expiration_days', 'length', 'max'=>3),

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

			array('s_icon', 'length', 'max'=>250),

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

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

			array('pk_i_id, fk_i_parent_id, i_expiration_days, i_position, b_enabled, b_price_enabled, s_icon', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	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(

			'fkIParent' => array(self::BELONGS_TO, 'TCategory', 'fk_i_parent_id' ),

			'tCategories' => array(self::HAS_MANY, 'TCategory', 'fk_i_parent_id'),

			'tLocales' => array(self::MANY_MANY, 'TLocale', 't_category_description(fk_i_category_id, fk_c_locale_code)'),

			'tCategoryStats' => array(self::HAS_ONE, 'TCategoryStats', 'fk_i_category_id'),

			'tItems' => array(self::HAS_MANY, 'TItem', 'fk_i_category_id'),

			'tKeywords' => array(self::HAS_MANY, 'TKeywords', 'fk_i_category_id'),

			'tMetaFields' => array(self::MANY_MANY, 'TMetaFields', 't_meta_categories(fk_i_category_id, fk_i_field_id)'),

			'tPluginCategories' => array(self::HAS_MANY, 'TPluginCategory', 'fk_i_category_id'),

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'pk_i_id' => 'Pk I',

			'fk_i_parent_id' => 'Fk I Parent',

			'i_expiration_days' => 'Expiration Days',

			'i_position' => 'I Position',

			'b_enabled' => 'B Enabled',

			'b_price_enabled' => 'B Price Enabled',

			's_icon' => 'S Icon',

		);

	}


	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 *

	 * Typical usecase:

	 * - Initialize the model fields with values from filter form.

	 * - Execute this method to get CActiveDataProvider instance which will filter

	 * models according to data in model fields.

	 * - Pass data provider to CGridView, CListView or any similar widget.

	 *

	 * @return CActiveDataProvider the data provider that can return the models

	 * based on the search/filter conditions.

	 */

	public function search()

	{

		// @todo Please modify the following code to remove attributes that should not be searched.


		$criteria=new CDbCriteria;


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

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

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

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

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

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

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


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}


	/**

	 * Returns the static model of the specified AR class.

	 * Please note that you should have this exact method in all your CActiveRecord descendants!

	 * @param string $className active record class name.

	 * @return TCategory the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

      

        

        

      

}






below is my TCategoryDescription Controller




<?php


/**

 * This is the model class for table "t_category_description".

 *

 * The followings are the available columns in table 't_category_description':

 * @property string $fk_i_category_id

 * @property string $fk_c_locale_code

 * @property string $s_name

 * @property string $s_description

 * @property string $s_slug

 */

class TCategoryDescription extends CActiveRecord

{

	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 't_category_description';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

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

		// will receive user inputs.

		return array(

			array('fk_i_category_id, fk_c_locale_code, s_name,s_descripttion,s_slug', 'required','on'=>'create'),

                        array('s_name','unique','message' => "This Categroy name already exists."),

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

			array('fk_c_locale_code', 'length', 'max'=>5),

			array('s_name, s_slug', 'length', 'max'=>100),

			array('s_description', 'safe'),

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

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

			array('fk_i_category_id, fk_c_locale_code, s_name, s_description, s_slug', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	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(

                    

		);

	}

         

        

       

	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'fk_i_category_id' => 'Fk I Category',

			'fk_c_locale_code' => 'Fk C Locale Code',

			's_name' => 'S Name',

			's_description' => 'S Description',

			's_slug' => 'S Slug',

		);

	}


	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 *

	 * Typical usecase:

	 * - Initialize the model fields with values from filter form.

	 * - Execute this method to get CActiveDataProvider instance which will filter

	 * models according to data in model fields.

	 * - Pass data provider to CGridView, CListView or any similar widget.

	 *

	 * @return CActiveDataProvider the data provider that can return the models

	 * based on the search/filter conditions.

	 */

	public function search()

	{

		// @todo Please modify the following code to remove attributes that should not be searched.


		$criteria=new CDbCriteria;


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

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

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

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

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


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}


	/**

	 * Returns the static model of the specified AR class.

	 * Please note that you should have this exact method in all your CActiveRecord descendants!

	 * @param string $className active record class name.

	 * @return TCategoryDescription the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

      

      

}







below is my TCateoryStats Controller code





<?php


/**

 * This is the model class for table "t_category_stats".

 *

 * The followings are the available columns in table 't_category_stats':

 * @property string $fk_i_category_id

 * @property string $i_num_items

 *

 * The followings are the available model relations:

 * @property TCategory $fkICategory

 */

class TCategoryStats extends CActiveRecord

{

	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 't_category_stats';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

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

		// will receive user inputs.

		return array(

			array('fk_i_category_id', 'required'),

			array('fk_i_category_id, i_num_items', 'length', 'max'=>10),

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

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

			array('fk_i_category_id, i_num_items', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	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(

			'fkICategory' => array(self::BELONGS_TO, 'TCategory', 'fk_i_category_id'),

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'fk_i_category_id' => 'Fk I Category',

			'i_num_items' => 'I Num Items',

		);

	}


	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 *

	 * Typical usecase:

	 * - Initialize the model fields with values from filter form.

	 * - Execute this method to get CActiveDataProvider instance which will filter

	 * models according to data in model fields.

	 * - Pass data provider to CGridView, CListView or any similar widget.

	 *

	 * @return CActiveDataProvider the data provider that can return the models

	 * based on the search/filter conditions.

	 */

	public function search()

	{

		// @todo Please modify the following code to remove attributes that should not be searched.


		$criteria=new CDbCriteria;


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

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


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}


	/**

	 * Returns the static model of the specified AR class.

	 * Please note that you should have this exact method in all your CActiveRecord descendants!

	 * @param string $className active record class name.

	 * @return TCategoryStats the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

}






and my view i need like this …how i insert remainig data in table…