Томица Кораћ
Томица Кораћ

Reputation: 2662

Laravel, update all relations when deleting a record

I have two models, Position and User. They have a One to many relation between them.

When I delete a position, I want all the related users to be detached from that position and attached to a different one (found by id).

I'm sure it's simple enough, but I've tried doing it in a foreach loop, without success:

public function postDelete($position)
{
    $positionMembers = $position->users()->get();

    foreach ($positionMembers as $member) {
        $member->position_id = '4';

        // fixed copy/paste var name error
        $member->save()
    }

    // Was the position deleted?
    if($position->delete()) {
        // Redirect to the position management page
        return Redirect::to('admin/positions')->with('success', Lang::get('admin/positions/messages.delete.success'));
    }

    // There was a problem deleting the position
    return Redirect::to('admin/positions')->with('error', Lang::get('admin/positions/messages.delete.error'));
}

I've also tried:

$member->position()->associate($this->position->find(4));

but it doesn't work either. The position_id field always remains unchanged. Is there a more recommended way?

Upvotes: 2

Views: 4292

Answers (1)

Jarek Tkaczyk
Jarek Tkaczyk

Reputation: 81167

First off define without success, because it says nothing, and the code you're showing should work.

Anyway, I would suggest different approach, for using Eloquent save in a loop isn't the best way:

public function postDelete($position)
{
    DB::transaction(function () use ($position, &$deleted) {

       // run single query for update
       $position->users()->update(['position_id' => 4]);

       // run another query for delete
       $deleted = $position->delete();
    });

    // Was the position deleted?
    if($deleted) {
        // Redirect to the position management page
        return Redirect::to('admin/positions')->with('success', Lang::get('admin/positions/messages.delete.success'));
    }

    // There was a problem deleting the position
    return Redirect::to('admin/positions')->with('error', Lang::get('admin/positions/messages.delete.error'));
}

With this, you make sure users don't get updated if there's some error(exception thrown) when deleting position and you execute 2 queries, no matter how many users there are to update.

Upvotes: 6

Related Questions