CHtml::dropDownList and model attribute value

Hey Everyone,

I am completely new to PHP frameworks and after quite a bit of reading, it sounds like Yii is best overall.

Anyways, I have created an Image.php model, ImageController.php, and a new action in the controller "upload" with a corresponding view that has a dropDownList for selecting a category. The problem is every time I submit the form the $model->category_id is "not set" in the table. As I mentioned, I am very new to this and am really hoping I just missed something that will be obvious to someone with more experience.

Image.php Model




<?php


/**

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

 *

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

 * @property integer $id

 * @property string $filename

 * @property string $title

 * @property string $description

 * @property integer $category_id

 * @property integer $user_id

 *

 * The followings are the available model relations:

 */

class Image extends CActiveRecord

{

	/**

	 * Returns the static model of the specified AR class.

	 * @return Image the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'image';

	}


	/**

	 * @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('category_id, user_id', 'numerical', 'integerOnly'=>true),

			array('filename, title, description', 'length', 'max'=>255),

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

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

			array('id, filename, title, category_id, user_id', '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(

		'user'=>array(self::BELONGS_TO, 'user', 'id'),

		'comments'=>array(self::HAS_MANY, 'comment', 'img_id'),

		'category'=>array(self::BELONGS_TO, 'category', 'id'),

		'keywords'=>array(self::HAS_ONE, 'keywords', 'img_id'),

		);

	}


	/**

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

	 */

	public function attributeLabels()

	{

		return array(

			'id' => 'ID',

			'filename' => 'Filename',

			'title' => 'Title',

			'description' => 'Description',

			'category_id' => 'Category',

			'user_id' => 'User',

		);

	}


	/**

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

	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.

	 */

	public function search()

	{

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

		// should not be searched.


		$criteria=new CDbCriteria;


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

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

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

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

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

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


		return new CActiveDataProvider(get_class($this), array(

			'criteria'=>$criteria,

		));

	}

}



ImageController.php actionUpload()




	public function actionUpload()

	{

	    $model=new Image;

	

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

	    {

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

	        if($model->validate())

	        {

	        	$model->save();

	        }

	    }

	    $this->render('upload',array('model'=>$model));

	}



upload.php view file: row for dropDownList()




<div class="row">

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

		<?php

		// retrieve the models from db

		$models = Category::model()->findAll();

 

		// format models as $key=>$value with listData

		$list = CHtml::listData($models, 

                'id', 'category'); 

               // dropDownList() parameters: 1)input name 2)selected option 3)formatted data for list

		echo CHtml::activeDropDownList('category', 1, $list);

		?>

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

	</div>



Well looks like it was something fairly obvious that I had overlooked: so, for all the other newbs that run into this, all I had to do was set $model->category_id

to equal the value from my dropDownList before saving the model: DUH!




public function actionUpload()

	{

	    $model=new Image;

	

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

	    {

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

	        if($model->validate())

	        {

	        	$model->category_id = $_POST['category']; // added this line to make $model->category_id equal the dropDownList selected value

	        	$model->save(); // then save the record

	        }

	    }

	    $this->render('upload',array('model'=>$model));

	}



Where $_POST[‘category’] refers to the NAME of my dropDownList(parameter #1) in the upload.php view file.

I love the Yii so far! What an amazing tool!!!


$form->dropDownList($model,'category_id',$list);

You need to specify model and attribute to activeDropdownList, instead of name and select. You specify selected item by initializing the attribute.

/Tommy

Ahhh, in hindsight I can see that my little uh, “workaround” wasn’t the way to go at all. :mellow:

In my view file I changed the code to use:




$form->dropDownList($model, 'category_id', $list)



This meant I could also remove that little workaround where I declared a value for the $model->category_id in my ImageController.php: so, I removed that part and now just the proper $model->save does all the work.

Thanks rudenich for the visual, and thanks tri for the explanation!