我定义了Student
和Seminar
模型之间的多对多关系。我怎样才能知道一个特定的学生是否参加了一个特定的研讨会?我想要实现的非工作示例如下所示:
$seminar->students()->contains($student->id);
使用上面的代码段时会显示以下错误:
BadMethodCallException,带有消息'调用未定义的方法Illuminate \ Database \ Query \ Builder :: contains()'
答案 0 :(得分:4)
尝试改为:
$seminar->students->contains($student->id);
假定$student
包含Student
模型的实例,您可以进一步简化它并使用:
$seminar->students->contains($student);
当您添加括号时,您正在使用Laravel查询构建器,并且您从未完成查询。要按照原来的方式进行,你需要:
$seminar->students()->get()->contains($student->id);
如果您想在提取学生时添加约束,此方法可能很有用。
但通常你可以省略括号并返回一个Collection,允许你使用像contains
这样的方法。
这样做的另一个好处是,一旦加载关系就不会重新查询数据库,因此通常会提供一种更有效的获取关系的方法。
如果您还没有加载学生,并希望使用数据库高效的检查方法,则可以使用:
$seminar->students()->where('students.id', $student->id)->exists();
答案 1 :(得分:1)
在您的情况下,例外是您在“查询生成器”上调用“ contains()”函数(用于Laravel集合)。应该是
$seminar->students->get()->contains($student->id);
但这是低效率的,因为这将检索研讨会的所有学生。
所以,
$seminar->students()->wherePivot('student_id', $student->id)->exists();
该方法将检查特定研讨会学生对的多对多中间表,并返回是否存在。
答案 2 :(得分:-1)
接受的答案是错误的。 $seminar->students()->exists($student->id)
不检查该关系是否存在。它仅检查学生是否存在。该学生可以属于任何研讨会,并且仍然会返回true。
在不从数据库中获取记录的情况下检查关系是否存在的正确方法是:
$seminar->students()->whereId($student->id)->exists()