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

ErikRobles's avatar

Trouble with relationships Laravel 8 Trying to access array offset of null

Hello. I am having some trouble getting some data to appear due to a relationship I don't quite have right yet. If I put an not null condition, the page works but I don't get the data that exists in the database but if I don't put in a not null condition, I get the following error:

Trying to access array offset on value of type null

If anyone can help me out in understanding why this relationship isn't working, I would sure appreciate it. Thank you in advance. Here is the table data in the view:

<tbody>
                @foreach($attendances as $attendance)
              <tr>
                <td>{{  ($attendance->date !=Null) ? date('m-d-Y', strtotime($attendance->date)) : "No data Yet."  }}</td>
                {{-- <td>{{  $attendance['getCompanyRelation']['name']  }}</td> --}}
                <td>{{ ($attendance->teacher_id !=Null) ? $attendance['getTeacherRelation']['name'] : "No Teacher Listed" }}</td>                
                <td>{{  $attendance->student->name  }}</td>
                <td>{{ $attendance->attend_status }}</td>

                <td>
                    <a href="{{ route('admin.pages.attendance.attendance_edit', $attendance->id) }}" class="btn btn-primary">Edit</a>
                    <a href="{{ route('admin.pages.attendance.attendance_delete', $attendance->id) }}" class="btn btn-danger">Delete</a>
                </td>
              </tr>
              @endforeach
            </tbody

Here is the Controller for the view:

 public function AttendanceReportView() {
        $data['attendances'] = Attendance::with('getTeacherRelation', 'getCompanyRelation', 'student')->orderBy('date', 'DESC')->get();
        // dd($data['attendances']); 
        return view('admin.pages.attendance.report_view', $data);
    }

And the model I am using:

class Attendance extends Model
{
    public function companyRelation() {
        return $this->belongsTo(Company::class, 'company_id', 'id');
    }

    public function student() {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }

    public function attendance() { 
        return $this->belongsTo(User::class, 'teacher_id', 'id');
    }

    public static function getAttendances() {
        $records = DB::table('attendances')->select('id', 'date', 'attend_status', 'teacher_id', 'user_id')->get()->toArray();

        return $records;
    }

    public function getTeacherRelation() {
        return $this->belongsTo(User::class, 'teacher_id', 'id');
    }

    public function getCompanyRelation() {
        return $this->belongsTo(Company::class, 'company_id', 'id');
    }

}

Again. Thank you in advance.

0 likes
18 replies
SilenceBringer's avatar

@erikrobles so, the problem is that you do not have getAttendanceRelation for one of your record.

Uncomment your condition

<td>{{$attendance->getAttendanceRelation ? $attendance->getAttendanceRelation->attend_status : "No Data Available for attendance: " . $attendance->id }}</td> --}}

and check your db manually for the given id

really - your structure looks strange. $data['allData'] = User you grab users, but next @foreach($allData as $attendance) call it attendance.

ErikRobles's avatar

@webrobert Thank you for your response. Yes, I get a null value for the relationship in question. When I run the code provided by @silencebringer I get the user_id's of the users that the attendance record belongs to. All the arrays that are returned in the dd() are null value for getAttendanceRelation

ErikRobles's avatar

@SilenceBringer That my friend is the problem I am trying to solve. I know I did this wrong but am not sure how to do it correctly.

webrobert's avatar

@erikrobles,

Your naming and relationships are confused. We've talked about naming before. If you talk thru in simple language what the relationship is you can name and create relationships properly. And not be confused.

class Attendance extends Model
{
    // does an attendance have a company? I doubt it, doesn't belong here.
    public function companyRelation() {
        return $this->belongsTo(Company::class, 'company_id', 'id');
    }

    public function student() {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }

    // does attendance attend it self. Wrong name. teacher
    public function attendance() {
        return $this->belongsTo(User::class, 'teacher_id', 'id');
    }

    // huh,     
    public static function getAttendances() {
        $records = DB::table('attendances')->select('id', 'date', 'attend_status', 'teacher_id', 'user_id')->get()->toArray();

        return $records;
    }

    // This is repeat of attendance() above
    public function getTeacherRelation() {
        return $this->belongsTo(User::class, 'teacher_id', 'id');
    }

    // another repeat from above
    public function getCompanyRelation() {
        return $this->belongsTo(Company::class, 'company_id', 'id');
    }

}

And what are you actually trying to do?

Show attendance to a student? Show attendance for class? None of this is evident from the code you posted. Either time.

ErikRobles's avatar

@webrobert Thank you for your reply. I will attempt to explain what it is exactly I am trying to do. I have a teacher who needs to input an attendance record for a particular student(user where role="Student"). That table for the student has id, name, company_id, teacher_id, level_id, exam, email, role, status, etc. In the attendance, I am essentially just collecting the date, teacher_id, student name and attendance status in the attendances table - id, date, teacher_id, user_id(user->id) and attend_status. All students have a teacher and a company associated with them when entered into the database. As of now, I am getting all relevant data in the view except for the company that the user works for (as they are corporate classes). The view is only for the admin to see the attendance record and be able to sort by company name. My main difficulty is understanding relations in laravel enough to display the company that is associated with the user(role = "Student"). I am new to relations so I will take your advice and follow the link you provided in the meantime. I really appreciate your help in understanding this thus the confusion in my code.

webrobert's avatar

@ErikRobles ahh, so attendance does have a company. I’ve gone mobile now. But that info is enough to actually help you.

1 like
ErikRobles's avatar

@webrobert I am going to see about those elequent fundaments course later today. Hopefullly it can help me make head or tails of what I am trying to do.

webrobert's avatar

@erikrobles

Wait, so to be clear Attendance doesnt have a company_id column?

attendances table - id, date, teacher_id, user_id(user->id) and attend_status.

And you're wanting attendance related to companies. Sounds like a company should have a related column. Simple language. "I want to see attendance for a company."

I think as a first pass, you'd do...

public function AttendanceReportView() {
    $attendance = Attendance::query()
            ->where('teacher_id', request('teacher_id')) // replace with how you are getting the id.
            ->with('student', 'company')
            ->orderBy('company_id', 'DESC')
            ->get();

    return view('admin.pages.attendance.report_view', $attendance);
}

What do you think? Can you change the columns?

ErikRobles's avatar

@webrobert Hello. Unfortunately it didn't work. I think what I have to do in create a company_id field in the table and then come up with a way to populate that field depending on the student begin registered for attendance and then I will have a simpler way of drawing out the company name in the end. I will write back once I have the function working. Thank you for your help. I am slowly starting to understand the relations and queries.

ErikRobles's avatar

@webrobert OK. I almost have it. I created the column in the db table attendance (company_id). I tested it and I can successfully add the company to the view from the add attendance page. However, one last problem remains and I haven't been able to find anything yet online to help me with this issue. In my company_id dropdown in the add page, I have multiples (which makes sense as I am looping through all the data in the db for company id's and there are multiples for different students that corespond to the teachers. For example, I have AcmeA 3 times, AcmeB 2 times and AmceC 4 times and these records are in the dropdown. As the project grows, so too will the number of companies per teacher. So what I need to do is have the dropdown only represent one of each company. Is there a fairly easy (hahaha) way of doing this? Here is the method:

public function AttendanceTeacherReportAdd() {
        $data['allData'] = User::where('role', 'Student')->get();
        $data['students'] = User::where('teacher_id', Auth::user()->id)->with('getCompanyRelation')->get();
        $data['levels'] = Level::all();
        $data['companies'] = User::with('getCompanyRelation')->where('teacher_id', Auth::user()->id)->select('name', 'company_id')->get();

        
        return view('admin.pages.attendance.attendance_add', $data);
    } 

The call in the view to add:

 <div class="col-md-3">
                        <div class="form-group">
                          <h5>Company Name <span class="text-danger">*</span></h5>
                          <div class="controls">
                              <select name="company_id[]" required class="form-control">
                                  <option value="" selected disabled>Select Company Name</option>
                                  @foreach($companies as $company)
                                      <option value="{{ $company->company_id }}">{{ $company->getCompanyRelation->name }}</option>
                                  @endforeach
                              </select>
                          </div>
                        </div>
                          {{-- End form Group --}}    
                      </div>
                      {{-- End Col md 3 --}}

Thanks a milllion for your help.

webrobert's avatar
Level 51

@ErikRobles why not do it the same way as the others?

$data['companies'] = Company::all();

Edit. My bad. I’m on my phone. Add distinct to what you have …

->distinct()->get();

But why aren’t you using the student data you already got twi lines before and take the companies from it then call unique

1 like
ErikRobles's avatar

@webrobert yes they do but I couldn't find a way to create the relation because it kept looking in my attendance table and until recently, I didn't have a company_id column. What I would like to end up doing is using an ajax call to trigger when the student name is entered into the dropdown to auto supply a hidden input field with the company_id. In this form the teacher can add many attendance records that contain the student name, and the student attendance status. If the teacher wants, he or she can add another record (or 20 if he or she likes) before hitting submit.

ErikRobles's avatar

@webrobert I would love to do exactly that but I get an elloquent error saying unique is undefined method on the Builder. Surely I must be doing it wrong. and yes, I can call from the student in my foreach to get the company id and name so thank you. I tried ->distinct()->get(); but that give me the duplicate records still but every little step I get closer.

ErikRobles's avatar

@webrobert Yes. it worked. Thank you. I looked up how to use the unique on the foreach and it worked like I expected. Thank you so much.

Please or to participate in this conversation.