Kael
Kael

Reputation: 169

Observer not running when creating in database

Hello I have this method that mass create student sections

Enrollment controller method this code works fine but it doesn't get in my studentSectionObserver. Although it's getting saved one by one with for loop.

public function setStudentsSection(Request $request)
    {
        $enrollments = Enrollment::whereIn('student_id', $request->students)->where('session_id', $request->session_id)->get();
        $program_section = ProgramSection::withCount('students')->find($request->program_section_id);
        if(($program_section->students_count + count($enrollments)) <= $program_section->max_students) {
            $new_student_sections = array();
            foreach($enrollments as $enrollment) {
                $data = [
                    'student_id'    => $enrollment->student_id,
                    'enrollment_id' => $enrollment->id,
                    'section_id'    => $request->program_section_id,
                    'created_at'    => Carbon::now()
                ];
                array_push($new_student_sections, $data);
            }
            return StudentSection::insert($new_student_sections);
        }
        return response()->json(['errors' => ['message' => 'Selected Section is full.']], 405);
    }

Then i output this activity with studentSectionObserver and added log::info but it doesn't log anything

public function created(StudentSection $student_section)
    {
        Log::info('test');
        $student = $student_section->student()->get()->first();
        $section = $student_section->section()->get()->first();
        Logger::createLog("Assigned " . $student->first_name . " " . $student->last_name . " '" . $section->section->name . "'");
    }

I know this observer gets triggered cause i tested it with this method whenever i add section the studentSectionObserver triggers Logger.

public function enrollStudent(EnrollmentRequest $request)
    {
        $check_if_exist = Enrollment::where('student_id', $request->student_id)->where('session_id', $request->session_id)->first();
        if (!$check_if_exist) {
            $program_section = ProgramSection::withCount('students')->find($request->section_id);
            if($program_section) {
                if($program_section->students_count < $program_section->max_students) {
                    $enrollment = Enrollment::create($request->all());
                    $section_data = ['student_id' => $request->student_id, 'section_id' => $request->section_id, 'enrollment_id' => $enrollment->id];
                    $section = StudentSection::create($section_data);
                    return response()->json($enrollment, 200);
                }
                return response()->json(['errors' => ['message' => 'Selected Section is full.']], 405);
            }
            $enrollment = Enrollment::create($request->all());
            return response()->json($enrollment, 200);
        } 
        return response()->json(['errors' => ['message' => 'Student is already enrolled in this session.']], 405);
    }

Any help would be greatly appreciated.

Upvotes: 0

Views: 703

Answers (3)

Asim
Asim

Reputation: 174

Laravel observer doesn't work on bulk objects, it only works with single object. So when you use create() function it will trigger the observer.

Upvotes: 0

Hesan Naveed
Hesan Naveed

Reputation: 251

As you have figured out the answer on your own.

The reason for using create method is because it triggers the event on the model. Same goes for update method.

Following is the update method under the hood:

   /**
     * Update the model in the database.
     *
     * @param  array  $attributes
     * @param  array  $options
     * @return bool
     */
    public function update(array $attributes = [], array $options = [])
    {
        if (! $this->exists) {
            return false;
        }

        return $this->fill($attributes)->save($options);
    }

And the save method has these lines of code:

 if ($this->fireModelEvent('saving') === false) {
    return false;
 }

Similarly, create method works. That's why insert doesn't trigger the event on model and you had to use create method.

Upvotes: 1

Kael
Kael

Reputation: 169

Turns out i just need to use create method.

public function setStudentsSection(Request $request)
    {
        $enrollments = Enrollment::whereIn('student_id', $request->students)->where('session_id', $request->session_id)->get();
        $program_section = ProgramSection::withCount('students')->find($request->program_section_id);
        if(($program_section->students_count + count($enrollments)) <= $program_section->max_students) {
            foreach($enrollments as $enrollment) {
                $response = StudentSection::create([
                    'student_id'    => $enrollment->student_id,
                    'enrollment_id' => $enrollment->id,
                    'section_id'    => $request->program_section_id,
                    'created_at'    => Carbon::now()
                ]);

                return $response;
            }
            
        }
        return response()->json(['errors' => ['message' => 'Selected Section is full.']], 405);
    }

Upvotes: 0

Related Questions