首先我们来看看AR是怎么来操作更新的
我们在控制器中新建一个方法 actionUpdate,将id=7的那行数据
public function actionUpdate($id){
// dump($id);
$id = trim($id);
//找出id符合条件的那一行(主键查找通过findByPk方法)
$model = User::model()->findByPk($id);
// dump($model);
//实现修改操作
$model->username = '张飞';
if(!$model->save()){
dump($model->getErrors());
}else{
dump('修改成功');
}
}

我们看到id为7的这行数据username已经变成 ‘张飞’
从update方法的逻辑我们可以看到,要想修改一条数据,需要先找到那条数据对应的AR对象,然后对对象的字段属性进行重新赋值,然后保存
那么这一系列的动作,yii又为我们做了些什么列
User::model()方法
实例化了一个User的单例,并绑定了User类的行为方法
public static function model($className=__CLASS__)
{
if(isset(self::$_models[$className]))
return self::$_models[$className];
else
{
$model=self::$_models[$className]=new $className(null);
$model->attachBehaviors($model->behaviors());
return $model;
}
}
findByPk()方法,第二和第三个参数还可以同时制定其他的查询条件
public function findByPk($pk,$condition='',$params=array())
{
Yii::trace(get_class($this).'.findByPk()','system.db.ar.CActiveRecord');
$prefix=$this->getTableAlias(true).'.';
//根据pk值 生成一个查询器对象
$criteria=$this->getCommandBuilder()->createPkCriteria($this->getTableSchema(),$pk,$condition,$params,$prefix);
return $this->query($criteria);
}
//执行查询
protected function query($criteria,$all=false)
{
$this->beforeFind();
$this->applyScopes($criteria);
if(empty($criteria->with))
{
if(!$all)
$criteria->limit=1;
$command=$this->getCommandBuilder()->createFindCommand($this->getTableSchema(),$criteria,$this->getTableAlias());
//创建一个cdbcommand对象,将查询出来的一行数据转成AR对象映射
return $all ? $this->populateRecords($command->queryAll(), true, $criteria->index) : $this->populateRecord($command->queryRow());
}
else
{
$finder=$this->getActiveFinder($criteria->with);
return $finder->query($criteria,$all);
}
}
//将查询出来的数组转成对象
public function populateRecord($attributes,$callAfterFind=true)
{
if($attributes!==false)
{
$record=$this->instantiate($attributes);
//设置模型的场景为update
$record->setScenario('update');
$record->init();
$md=$record->getMetaData();
foreach($attributes as $name=>$value)
{
if(property_exists($record,$name))
$record->$name=$value;
elseif(isset($md->columns[$name]))
$record->_attributes[$name]=$value;
}
$record->_pk=$record->getPrimaryKey();
$record->attachBehaviors($record->behaviors());
if($callAfterFind)
$record->afterFind();
return $record;
}
else
return null;
}
在save方法中,通过_new判断对象不是新的记录,所以执行了Update方法
public function update($attributes=null)
{
if($this->getIsNewRecord())
throw new CDbException(Yii::t('yii','The active record cannot be updated because it is new.'));
if($this->beforeSave())
{
Yii::trace(get_class($this).'.update()','system.db.ar.CActiveRecord');
if($this->_pk===null)
$this->_pk=$this->getPrimaryKey();
$this->updateByPk($this->getOldPrimaryKey(),$this->getAttributes($attributes));
$this->_pk=$this->getPrimaryKey();
$this->afterSave();
return true;
}
else
return false;
}
更新和添加用的表单基本是一样的,所以我们通常使用同样的表单视图,如
controller中
public function actionUpdate($id){
// dump($id);
$id = trim($id);
//找出id符合条件的那一行(主键查找通过findByPk方法)
// dump(User::model());
$model = User::model()->findByPk($id);
$this->performAjaxValidation($model);
// dump($model);
if(!empty($_POST['User']) && Yii::app()->request->isPostRequest){
// dump($_POST);
//实现修改操作
$model->attributes = $_POST['User'];
if(!$model->save()){
dump($model->getErrors());
}else{
dump('修改成功');
}
}
$this->render('update',array(
'model'=>$model,
));
}
views/user/update.php
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'user-active_form-form',
// Please note: When you enable ajax validation, make sure the corresponding
// controller action is handling ajax validation correctly.
// See class documentation of CActiveForm for details on this,
// you need to use the performAjaxValidation()-method described there.
'enableAjaxValidation'=>true,
// 'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
'validateOnChange'=>true,
),
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username',array('style'=>'height:25px;')); ?>
<?php echo $form->error($model,'username'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'city_id'); ?>
<?php echo $form->dropDownList($model,'city_id',User::getCitys(),array('prompt'=>'请选择','style'=>'height:25px;width:100px;')); ?>
<?php echo $form->error($model,'city_id'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord?'添加':'修改',array('style'=>'width:60px;height:30px;')); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->