D'Arcy Rail-Ip
D'Arcy Rail-Ip

Reputation: 11955

Why is dissociate not working immediately on my Laravel model?

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

Answers (1)

patricus
patricus

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

Related Questions