【问题标题】:On update, skip certain attributes from updating yii更新时,跳过某些属性更新 yii
【发布时间】:2013-12-05 12:32:01
【问题描述】:

我需要停止更新某些值,即使这些值设置为 POST 数组。为此,我在 yii 规则中使用了 unsafe。

array('id', 'unsafe', 'on'=>'update'),

仍然如此,我无法跳过更新的 id。

如何用 yii 做到这一点?

下面是我的规则函数..

public function rules()
{
    // NOTE: you should only define rules for those attributes that
    // will receive user inputs.
    return array(
        array('name, body, created_date', 'required'),
        array('name', 'length', 'max'=>128),
        array('body', 'length', 'max'=>512),
        array('id', 'unsafe', 'on'=>'update'),
        // The following rule is used by search().
        // @todo Please remove those attributes that should not be searched.
        array('id, name, body, created_date', 'safe', 'on'=>'search'),
    );
}

更新 1

$model->属性 = $_POST['U​​ser'];

我需要在保存时跳过某些属性。

$model->save();

【问题讨论】:

  • 可以添加更新功能吗?
  • @secretlm 它不是一个函数。这是一个场景。
  • “我需要停止更新某些值,即使这些值设置为 POST 数组” => 我想查看您在“更新”操作中为模型属性设置值的代码。
  • @secretlm 请检查更新的问题

标签: php yii model


【解决方案1】:

当您在控制器中创建新模型实例时,您需要声明场景 例如 如果你的声明是这样的

$myModelInstance = new MyModel();

你需要把它改成

$myModelInstance = new MyModel('update');

但是,如果您使用活动记录的一种查找方法来保存它,那么它会自动设置为“更新”,如下所示:http://www.yiiframework.com/doc/api/1.1/CActiveRecord#save-detail

如果您使用其他逻辑来声明模型,您可以简单地使用 setScenario 函数

$myModel->setScenario("update"); 

【讨论】:

    【解决方案2】:

    正如 Manquer 所提到的,您的场景可能没有设置为更新。正确的更新顺序将涉及加载现有对象实例、分配变量然后保存它们。我个人永远不会仅仅实例化一个对象并给它一个不同的场景,我认为这是在问问题。

    // Load the existing object first
    $user = User::model()->findByPk(..);
    // Assign everything that has either a validation rule or is added as "safe"
    $user->attributes = $_POST['User'];
    // Save the updated version
    $user->save();
    

    Yii 知道不更新“id”(如果它被正确定义为数据库中的主键)。无需将其标记为不安全。 所以:确保实例是从数据库加载的($user->isNewRecord 应该是 FALSE)并且表有一个 PK。然后更新你想要的属性。

    您也只能通过“清理” $_POST 来更新特定属性,或者在调用 save 时将其调用为 $user->save(true, array('name', 'body')) 以仅更新名称例如身体。

    【讨论】:

    • 因此没有其他方法可以像拥有一个不安全数组 unsafe('id','created_date') 并且不会添加或更新 unsafe 数组中的属性,并将保留旧值在数据库中。像这样从模型级别完成的事情?
    • 由于您在“更新”场景中添加了不安全的验证器,因此您必须确保您的模型处于该场景中,Manquer 向您展示的方式。我真的不明白你使用这样的 ActiveRecord 模式有什么意义(因为你正在规避一切:))。您可能只想使用 DAO 访问(Yii::app()->db->createCommand 等)
    • 谢谢。对这个问题有什么要说的吗? stackoverflow.com/questions/20142553/…
    【解决方案3】:

    对于Yii2

    如果不想使用场景,因为您必须手动应用它们,您可以在 rules() 中使用 when

    ['moduleID', 'required', 'when' => function($model, $attribute) {
        return $model->isNewRecord;
    }],
    

    或者,如果您有许多属性规则并且不想将when添加到所有规则中,您可以简单地禁止beforeSave()方法中的更改:

    public function beforeSave($isInsert) {
        $attribute = 'moduleID';
        if (!$isInsert && $this->isAttributeChanged($attribute)) {
            $this->addError($attribute, 'You cannot change this.');
        }
    
        return parent::beforeSave($isInsert);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-01
      • 2016-12-01
      • 2011-06-26
      • 2015-01-26
      • 1970-01-01
      • 1970-01-01
      • 2011-07-15
      相关资源
      最近更新 更多