How to check if one record is attached to another?
Solution 1
Try instead:
$seminar->students->contains($student->id);
Presuming $student
contains an instance of the Student
model you can simplify it further and just use:
$seminar->students->contains($student);
When you add parentheses you're using the Laravel query builder, and you never completed the query. To do it in the manner you had originally you would need:
$seminar->students()->get()->contains($student->id);
This method could be useful if you wanted to add constraints when fetching your students.
But generally you can omit the parentheses and a Collection will be returned, allowing you to use methods like contains
.
This has the additional benefit of not re-querying the database once the relationship is loaded, so will generally be a far more efficient means of fetching relationships.
If you haven't already loaded the students and want a database efficient method of checking you could instead use:
$seminar->students()->where('students.id', $student->id)->exists();
Solution 2
In your case the exception is you are calling 'contains()' function (which is for Laravel Collection) on 'Query Builder'. It should be
$seminar->students->get()->contains($student->id);
but this is inefficient since this will retrieve all the students of the seminar.
so instead,
$seminar->students()->wherePivot('student_id', $student->id)->exists();
this method will check in the intermediate table of many to many relationship for particular seminar-student pair, and will return whether exists or not.
Alex Lomia
Updated on June 16, 2022Comments
-
Alex Lomia almost 2 years
I have defined a many-to-many relationship between
Student
andSeminar
models. How can I find out if one particular student is attending one particular seminar? Non-working example of what I want to achieve is illustrated below:$seminar->students()->contains($student->id);
The following error is shown when using the above code snippet:
BadMethodCallException with message 'Call to undefined method Illuminate\Database\Query\Builder::contain()'
-
Alex Lomia almost 8 yearsThanks for an answer. Wouldn't that introduce an unnecessary load on the DB? Since it retrieves all of the students of the given
$seminar
from the database and only after that it checks the array withcontains()
-
Matt McDonald almost 8 yearsYes. In which case you can't use
contains
as it's a Collection method. You'd instead need something like:$seminar->students()->exists($student -> id);
-
Alex Lomia almost 8 yearsThank you, the
exists()
method was exactly what I was looking for -
Agil over 6 years@MattMcDonald I have a simular issue too, do you think I can somehow use
$seminar->students()->exists($student->id);
inside an if statement? I never used many to many before so I'm having quite a little trouble with it. -
Matt McDonald over 5 years
$seminar->students()->exists($student->id)
and$seminar->students->exists($student->id)
do very different things - note there are no()
in the solution. -
jgawrych about 5 yearsNot sure if this has changed in laravel, but
exists()
doesn't take any parameters as of 5.7. The last code example will ignore the parameter and make a DB call to check if any students exist in the seminar, not just a specific one.