Activerecord 在Yii中一起在控制器中保存和更新

Activerecord 在Yii中一起在控制器中保存和更新,activerecord,model,yii,controller,Activerecord,Model,Yii,Controller,我的数据库中有两个表,users和profile。配置文件将用户id作为主键。每个用户只能有一个配置文件。当我上传一个图像文件时,它的名称存储在具有该用户id的配置文件表中。当配置文件表中有其他字段要更新时,我首先检查是否已经有具有该用户id的记录。在我的配置文件模型中,我已写入 public function checkForSaveOrUpdate() { return self::model()->findByAttributes(array('user_id'=>Yi

我的数据库中有两个表,users和profile。配置文件将用户id作为主键。每个用户只能有一个配置文件。当我上传一个图像文件时,它的名称存储在具有该用户id的配置文件表中。当配置文件表中有其他字段要更新时,我首先检查是否已经有具有该用户id的记录。在我的配置文件模型中,我已写入

public function checkForSaveOrUpdate()
{
    return self::model()->findByAttributes(array('user_id'=>Yii::app()->user->id));
}
我的控制器文件看起来像这样

    public function actionCreateInfo()
      {
        $profile = new Profile;
        $profile->user_id = Yii::app()->user->id;

        if(isset($_POST['Profile']))
        {
            if($profile->checkForSaveOrUpdate() === null)
            {
                $profile->attributes = $_POST['Profile'];
                if($profile->save())
                    Yii::app()->user->setFlash('success','Profile has been saved successfully');
            }
            elseif($profile = $profile->checkForSaveOrUpdate())
            {
                $profile->attributes = $_POST['Profile'];
                if($profile->update())
                    Yii::app()->user->setFlash('success','Profile has been updated successfully');
            }

            $this->redirect(array('index'));
        }

        $this->render('createInfo',array('profile'=>$profile));
}

我的问题是,当我在数据库、配置文件中已经有一条记录,并且我提交了一个新表单时,旧数据将被全部删除,只有提交的当前值会被更新,而它应该保留旧值,只更新新值。

如果您像这样安装模型:

$model = new YourModel;
您将把
$model->isNewRecord
设置为
true

var_dump($model->isNewRecord); // true, in this case you use $model->save()
找到记录时,同一属性将具有相反的值:

$model = YourModel::model()->findByPk(1);
var_dump($model->isNewRecord); // false - and now you use $model->update(), instead.

如果将模型安装为:

$model = new YourModel;
您将把
$model->isNewRecord
设置为
true

var_dump($model->isNewRecord); // true, in this case you use $model->save()
找到记录时,同一属性将具有相反的值:

$model = YourModel::model()->findByPk(1);
var_dump($model->isNewRecord); // false - and now you use $model->update(), instead.

将函数更改为静态函数

 public static function checkForSaveOrUpdate()
    {
        return self::model()->findByAttributes(array('user_id'=>Yii::app()->user->id));
    }
然后将操作修改为

public function actionCreateInfo()
{
        $profile = Profile::checkForSaveOrUpdate();
        if($profile===null)
        {
            $profile=new Profile;
            $profile->user_id = Yii::app()->user->id;
        }
        if(isset($_POST['Profile']))
        {
            $profile->attributes = $_POST['Profile'];
            if($profile->save())
                Yii::app()->user->setFlash('success','Profile has been saved successfully');
           $this->redirect(array('index'));
        }

        $this->render('createInfo',array('profile'=>$profile));
}

将函数更改为静态函数

 public static function checkForSaveOrUpdate()
    {
        return self::model()->findByAttributes(array('user_id'=>Yii::app()->user->id));
    }
然后将操作修改为

public function actionCreateInfo()
{
        $profile = Profile::checkForSaveOrUpdate();
        if($profile===null)
        {
            $profile=new Profile;
            $profile->user_id = Yii::app()->user->id;
        }
        if(isset($_POST['Profile']))
        {
            $profile->attributes = $_POST['Profile'];
            if($profile->save())
                Yii::app()->user->setFlash('success','Profile has been saved successfully');
           $this->redirect(array('index'));
        }

        $this->render('createInfo',array('profile'=>$profile));
}

您的
POST
数据可能包括所有模型属性,包括用户设置为空字符串而保留为空的属性;除非模型规则中另有规定,否则空字符串是大规模赋值的可接受值;大量分配是指您实际使用
$profile->attributes=$\u POST['profile']执行的操作

一种解决方案是在控制器中取消设置那些您不想更新的属性,例如那些包含空字符串的属性

但是这种规则应该在模型中定义,并通过调用
validate()
方法触发,您现在通过调用
update()
跳过该方法。您最好调用
save()
,因为内部调用
validate()
,而不是
update()

默认值的规则定义如下:

array(
    'attr_name',
    'default',
    'setOnEmpty' => true,
    'value' => null
)

您的
POST
数据可能包括所有模型属性,包括用户设置为空字符串而保留为空的属性;除非模型规则中另有规定,否则空字符串是大规模赋值的可接受值;大量分配是指您实际使用
$profile->attributes=$\u POST['profile']执行的操作

一种解决方案是在控制器中取消设置那些您不想更新的属性,例如那些包含空字符串的属性

但是这种规则应该在模型中定义,并通过调用
validate()
方法触发,您现在通过调用
update()
跳过该方法。您最好调用
save()
,因为内部调用
validate()
,而不是
update()

默认值的规则定义如下:

array(
    'attr_name',
    'default',
    'setOnEmpty' => true,
    'value' => null
)

你能详细解释一下你为什么要求我将其设置为静态吗?在这里,你首先检查(即在渲染视图之前)此记录是否存在于配置文件中。如果该用户已经存在于配置文件中,则它首先加载数据,然后渲染到视图(createInfo)。如果配置文件表中没有这样的用户,它将创建一个。您能否详细说明为什么要让我将其设置为静态?在这里,您首先检查(即在渲染视图之前)此记录是否存在于配置文件中。如果该用户已存在于配置文件中,它将首先加载数据,然后渲染到视图(createInfo)。如果配置文件表中没有这样的用户,它将创建一个。您如何同时执行这两项操作?我的意思是,最初你要求我制作一个新的$model,然后由findByPk检查?这就是我在模型类中编写函数的原因。你怎么能同时做到这两个呢?我的意思是,最初你要求我制作一个新的$model,然后由findByPk检查?这就是我在模型类中编写函数的原因。