Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jvezina's avatar

Updating models within a collection (without saving to the db)

I have a problem updating models and relationships. And what's important is that I need to do it to what's in memory and not save the changes to the database (so no "save()").

Here's an example of what I'm trying to do with these three classes (it's a contrived example to make it simpler to explain).

class Course extends Model { public function students() { return $this->hasMany('App\Student'); } } class Student extends Model { public function assignments() { return $this->hasMany('App\Assignment'); } public function course() { return $this->belongsTo('App\Course'); } } class Assignment extends Model { public function student() { return $this->belongsTo('App\Student'); } }

I select the course and all its students and their grades.

Now I need to update grades on some of the assignments already recorded for the student and add new assignments. I'll also want to do the same thing with students (& their assignments), so the solution needs to keep all the relationships.

What works - but is ugly is:

// $selectedStudent is student model who's assignments (a collection) I want to update (update existing assignment and adding new assignment ) // $newAssignments is a collection of the new assignment models that either need to be updated or added

// first update the existing assignment foreach ($selectedStudent->assignments as $k=>$v) { $assignmentName = $v->getAttribute('assignmentName'); $assignmentUpdate= $newAssignments->where('assignmentName', $assignmentName)->first(); if ($assignmentUpdate) { $selectedStudent->assignments->forget($k); $v->setAttribute('grade', $updatedGrade->getAttribute('grade')); $selectedStudent->assignments->push($v); } }

// now add the assignment models that haven't been previously recorded foreach ($newAssignmentsas $v) { $assignmentName = $v->getAttribute('assignmentName'); $existingAssignment = $selectedStudent->assignments()->where('assignmentName', $assignmentName)->first(); if (!$existingAssignment ) { $selectedStudent->assignments->push($v); } }

And to repeat two of the constraints:

  1. I don't want to save any of these changes to the database.
  2. I need to keep the relationships so the same approach can be used to update the students in the class

Seems like there's got to be a better way to do it.

0 likes
1 reply

Please or to participate in this conversation.