假设我有与 B 相关的模型 A。
当我写:
$a = A::model()->findByPK(1);
$a->B->doSomething();
现在 B 可能会被更改(例如由其他用户更改)。当我写:
$a->B->doSomething();
它使用 B 的旧值。我应该做什么来强制在 doSomething() 之前刷新 B 的值。
Yii 提供了一个 refresh() 方法,我认为这就是你想要的?
http://www.yiiframework.com/doc/api/CActiveRecord#refresh-detail
您可以通过以下方式获得刷新的“B”值:
$a->getRelated('B',true)->doSomething();
第二个参数 "true" 要求 yii 从数据库中重新加载关系。
在 Yii2 中它只是一个简单的
unset($model->relation);
所以在这种情况下unset($a->b)
据我了解,当在 A 的模型中声明关系 B 时,当您调用 $a->B 时,对象 B 正在从数据库中“延迟加载”。除非它被缓存(默认情况下我不认为它不会这样做)它应该在每次调用该关系时获取 B 的新副本。
我会确保如果 doSomething() 正在更改 B 中的数据,您也会在 B->doSomething() 中调用 $this->save()。如果您正在更改 B 但不保存更改,那么当您再次查询 B 时,它将具有相同的旧内容。
<?php
function doSomething() {
$this->my_data++; // change something
$this->save(); // save the changes
}
?>
如果您想在更改 B 之后但在保存之前再次访问它,您需要将其设置在 A 中的一个变量中以“缓存”它,有点。否则,由于当您调用 $a->B 时它会从数据库中获取新副本(并且您没有在 doSomething() 中保存更改),因此您将拥有旧数据。像这样的东西会起作用:
<?php
$a = A::model()->findByPK(1);
$B = $a->B; // save B
$B->doSomething(); // change B
$B->doSomething(); // change the changed B again
$B->save(); // save both changes
?>
如果是一般并发问题(听起来可能是“它被另一个用户更改了”),您可能需要实现某种锁定机制,或者使用 mySql 事务(通过 Yii 的 CDbTransaction)来确保数据正直。
如果这些都不起作用,也许做一个“急切”的加载也可以解决你的问题,就像这样:
<?php
$posts=A::model()->with('B')->findAll();
?>
$a->B->refresh();// 只刷新B
$a->refresh();// 刷新 a 和所有自然包括 "B" 的关系