tags:

views:

106

answers:

2

let's say I have model A with relation to B.

When I write:

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

and now B may by changed (by other user for instance). When I write:

$a->B->doSomething(); 

it uses old values of B. What I should do to force to refresh value of B before doSomething().

A: 

As I understand it when the relationship B is declared in A's model, the object B is being "lazy loaded" from the database when you call $a->B. Unless it is being cached (which it doesn't do by default I don't think) it should be grabbing a fresh copy of B each time you call that relationship.

I would make sure that if doSomething() is changing the data in B that you also call $this->save() inside B->doSomething(). If you are changing B but not saving the changes then when you query for B again it will have the same old content.

<?php 
function doSomething() {
    $this->my_data++; // change something
    $this->save();  // save the changes
} 
?>

If you want to access B again after you have changed it but before you have saved it, you will need to set it in a variable in A to "cache" it, sort of. Otherwise, since it's getting a fresh copy from the database when you call $a->B (and you didn't save the change in doSomething()), you will have the old data. Something like this will work instead:

<?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
?>

If it is a general concurrency issue (which it sounds like it might be when you say "it's changed by another user"), you may need to implement some sort of lock mechanism, or use mySql transactions (via Yii's CDbTransaction) to ensure data integrity.

If none of this works, perhaps doing an "eager" load will fix your problem as well, like so:

<?php 
$posts=A::model()->with('B')->findAll();
?>
thaddeusmt
+2  A: 

Yii provides a refresh() method I think thats what your looking for?

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

Sniper