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

ErikRobles's avatar

Relation Laravel 8 returning one relation but not other

Hello. I am putting together a laravel 8 app and this is the first time I am working with relationships. I have hit a brick wall and am hoping someone can throw me a lifesaver ( or a raft). I am simply trying to return a view showing data from a couple of different tables. So far, I have been able to get most of the data I need but one of my relationships is not set up right but as I am a novice in this, I don't know what I am doing wrong. If someone can shed some light on this for me, I would surely appreciate it.

The error I am getting is:

Trying to access array offset on value of type null 

my DB tables that I am working wtih are:

Companies which hold the columns id and name
Students which hold the columns id, name, teacher_id, level_id, company_id
Attendances which hold the columns id, month, day, student_id, attend_status

In my General Attendance view, I want to display a table of records showing Month, Day, Company Name, Student Name, Attendance Status and two buttons (edit, delete).

In my Attendance Controller I have:

 public function AttendanceReportView() {
        $data['allData'] = Attendance::with('studentRelation', 'companyRelation')->get();  
        return view('admin.pages.attendance.report_view', $data);
    }

In my Attendance Model, I have the following:

<?php

namespace App\Models;

use App\Models\Company;
use App\Models\Student;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

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

    public function studentRelation() {
        return $this->belongsTo(Student::class, 'student_id', 'id');
    }
}

And finally the view. I am not getting my Company Names:

<table class="table table-hover text-nowrap">
            <thead>
              <tr>
                <th>Month</th>
                <th>Day</th>
                <th>Company</th>
                <th>Student</th>
                <th>Attend Status</th>
                <th>Action</th>
              </tr>
            </thead>
            <tbody>
                @foreach($allData as $attendance)
              <tr>
                <td>{{ $attendance->month }}</td>
                <td>{{ $attendance->day }}</td>
                <td>
                    {{ $attendance['companyRelation']['name'] }}
                </td>
                <td>{{ $attendance['studentRelation']['name'] }}</td>
                <td>{{ $attendance->attend_status }}</td>
                <td>
                    <a href="" class="btn btn-primary">Edit</a>
                    <a href="" class="btn btn-danger">Delete</a>
                </td>
              </tr>
              @endforeach
            </tbody>
          </table>

Again, any help will go a long way in my development. Thank you.

Edit:: I am a bit closer. I changed my controller to a DB facades in the following way:

public function AttendanceReportView() {
        $data['companies'] = DB::table('students')->join('companies', 'students.company_id', "=", 'companies.id')
        ->join('attendances', 'attendances.student_id',  "=", 'students.id')
        ->select('companies.name')
        ->get();
        
        $data['allData'] = Attendance::with('studentRelation', 'companyRelation')->get();
        
        return view('admin.pages.attendance.report_view', $data);
    }

in my view, I changed the code to the following:

 <tbody>
                @foreach($allData as $attendance)
              <tr>
                <td>{{ $attendance->month }}</td>
                <td>{{ $attendance->day }}</td>
                <td>
                    {{ $companies }}
                </td>
                <td>{{ $attendance['studentRelation']['name'] }}</td>
                <td>{{ $attendance->attend_status }}</td>
                <td>
                    <a href="" class="btn btn-primary">Edit</a>
                    <a href="" class="btn btn-danger">Delete</a>
                </td>
              </tr>
              @endforeach
            </tbody>

This does get me the name of the company in the view but I am not sure how to call it so it just shows me the name once. In my case, it is showing me the array looped exactly the number of records I have. For example if I have four records, I see and array showing the company name 4 times in array format. So, finally, my question is how to display the name of the company just once. Thanks.

0 likes
2 replies
SilenceBringer's avatar
Level 55

@erikrobles your attendance do not belongsTo company, because I do not have company_id. Instead, student belongsTo company.

so, in your attendance model

    public function student() {
        return $this->belongsTo(Student::class);
    }

in your student model

    public function company() {
        return $this->belongsTo(Company::class);
    }

load data as

Attendance::with('student.company')->get(); 

and output it as

                <td>
                    {{ $attendance->student->company->name }}
                </td>
                <td>{{ $attendance->student->name }}</td>

Also you can look at hasOneThrough relationship https://laravel.com/docs/8.x/eloquent-relationships#has-one-through to define company relationship directly in attendance model

2 likes
ErikRobles's avatar

@SilenceBringer Thank you so very much. Yeah, I was really scratching my head trying to figure out what has many and what belongs to what. Thanks a million. Your help will go a long way. Cheers.

1 like

Please or to participate in this conversation.