Elvis Kirui
Elvis Kirui

Reputation: 101

Property [students] does not exist on this collection instance

So i have relationship declared on the parents Model as

 <?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Parents extends Model
{
  protected $fillable = [
      'firstName',
      'middleName',
      'lastName',
      'phoneNumber',
      'gender',
  ];
  public function students(){
    return $this->belongsToMany('App\Student','parent_student','parentId','studentId');
  }

}

with the anchor table parent_student and a students table with the column classId. here is the students model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Student extends Model
{
  //
  protected $fillable = [
    'firstName',
    'middleName',
    'lastName',
    'regNo',
    'gender', 
    'dob',        
    'classId',
  ];

  public function parents(){
    return $this->belongsToMany('App\Parents','parent_student','studentId','parentId');
  }

  public function classes()
  {
    return $this->belongsTo('App\Classes','classId');
  }
}

what i am tring to achieve is to get the email addresses for parents with students in one class eg class 1, which i pass the classId from a dropdown select in a form on the view to the controller.

Here is my controller.

public function submitEmail(Request $request)
    {
      $validatedData = $request->validate([
        'class' => 'required|integer',
        'message' => 'string|max:255',
        'subject' => 'string|max:255',
      ]);
      $class = $request->input('class');
      $message = $request->input('message');
      $subject = $request->input('subject');
  $parents = Parents::all();
        $parents = Parents::where($parents->students->classId,"=",$class)->get();
        die($parents);


}

I am fairly new to laravel and this is the far i have gone so far.Any suggestions would be much appreciated.(I am using laravel 5.6)

Upvotes: 1

Views: 1096

Answers (2)

Tim Lewis
Tim Lewis

Reputation: 29297

This line

$parents->students

is where your problem is. $parents is a Collection (array) of Parents models, not a single Parents1 model. To get a single classId, you need to use a Loop:

foreach($parents AS $parent){
  ... // Should be able to access $parent->students without issue;
}

Next, you're trying to access ->classId of $parent->students, which is the same issue. $parent->students is a Collection, and not a single Student2 model. You'd need another loop to get the classId:

foreach($parents AS $parent){
  foreach($parent->students AS $student){
    ... // Should be able to access `$student->classId` without issue
  }
}

But, this still doesn't solve your core issue. It's important to know when you're accessing a Collection vs a single Model, so keep that in mind.

All of that aside, it sounds like you're trying to get all the Parents of Students in Class of $class (passed from your <form>). To accomplish this, you can use ->whereHas(), as below:

$parents = Parents::whereHas("students", function($query) use($class){
  $query->where("classId", "=", $class);
})->with(["students" => function($query) use($class){
  $query->where("classId", "=", $class);
}])->get();

What this does, is queries the parents table for any student records that have a class with an id of $class.

Note that whereHas and with contains the same subquery to constrain and eager-load each Parents collection of Students to what's required.

Sidenote: Your classes() relationship on Student has an issue. Since it's a belongsTo() method, it should be class() (singular), as $student->classes would only return a single Class model.


1 Pay attention to naming conventions. Parents should be Parent; Model names are singular.
2 You named the Student Model right, so be consistent.

Upvotes: 4

Max Maximilian
Max Maximilian

Reputation: 600

Try this query:

$parents = Parents::with(['students' => function($query) use ($class){
    $query->where('classId',$class);
}])->get();

Instead of:

$parents = Parents::where($parents->students->classId,"=",$class)->get();

Then instead of die($parents) use dd($parents)

Upvotes: 0

Related Questions