11

假设我有与 B 相关的模型 A。

当我写:

$a = A::model()->findByPK(1);
$a->B->doSomething();

现在 B 可能会被更改(例如由其他用户更改)。当我写:

$a->B->doSomething(); 

它使用 B 的旧值。我应该做什么来强制在 doSomething() 之前刷新 B 的值。

4

5 回答 5

18

Yii 提供了一个 refresh() 方法,我认为这就是你想要的?

http://www.yiiframework.com/doc/api/CActiveRecord#refresh-detail

于 2010-07-19T21:39:13.397 回答
10

您可以通过以下方式获得刷新的“B”值:

$a->getRelated('B',true)->doSomething(); 

第二个参数 "true" 要求 yii 从数据库中重新加载关系。

于 2013-03-13T22:27:55.253 回答
7

在 Yii2 中它只是一个简单的

unset($model->relation);

所以在这种情况下unset($a->b)

于 2015-03-25T22:56:25.200 回答
0

据我了解,当在 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();
?>
于 2010-07-16T20:12:07.397 回答
0

$a->B->refresh();// 只刷新B

$a->refresh();// 刷新 a 和所有自然包括 "B" 的关系

于 2017-02-02T15:46:07.160 回答