Reputation: 11955
Here is some of my code:
class User extends Model {
public function orders() {
return $this->hasMany('App\Order');
}
public function emptyCart() {
$orders = $this->orders;
foreach($orders as $order) {
$order->user()->dissociate();
$order->save();
}
if ($this->orders) {
echo 'Orders still exist?'
}
}
}
My echo statement is being hit. If I refresh my app, there are no orders attached, but immediately after I "empty" my cart, it is returning orders as if I hadn't removed them...
Interestingly, the "order" models that get returned have user_id
set as null.
Upvotes: 1
Views: 6924
Reputation: 62278
$this->orders
is a relationship attribute. Once the relationship is loaded (via eager loading or lazy loading), the relationship will not be reloaded unless explicitly done in the code.
So, in the beginning of your function, you access the $this->orders
attribute. If the orders have not been loaded yet, they will be lazy loaded at this point. You then go through and dissociate the orders from the user. This correctly sets the user_id
to null, and updates the database (with your save()
), but it will not remove the items from the Collection that is already loaded.
If you would like the $this->orders
attribute to reflect the current state of the relationships after you're done modifying the relationships, you will need to explicitly reload the relationship. Example below:
public function emptyCart() {
// gets the Collection of orders
$orders = $this->orders;
// modifies orders in the Collection, and updates the database
foreach($orders as $order) {
$order->user()->dissociate();
$order->save();
}
// reload the relationship
$this->load('orders');
// now there will be no orders
if ($this->orders) {
echo 'Orders still exist?'
}
}
Upvotes: 8