Laravel 通过 属性 获取 eloquent 查询构建器关系
Laravel get eloquent query builder relations by property
我正在使用 eloquent 查询构建器根据用户搜索查询提供的参数有条件地构建搜索查询。
这似乎适用于直接属于我正在搜索的模型的属性。但是,我在尝试 return 与模型相关但不直接属于模型的其他结果时遇到问题。
我到底想做什么:
我正在尝试允许用户通过中介 table.
按教师姓名搜索学校,其中 name/keyword 出现在学校的关系中
这是我的模型和关系:
学校:
class School extends Authenticatable
{
protected $fillable = [
'school_name', 'head_teacher', 'address'
];
public function teachers()
{
return $this->belongsToMany(Teacher::class, 'teacher_links', 'school_id', 'teacher_id');
}
}
老师:
class Teacher extends Authenticatable
{
use Notifiable;
protected $table = 'teacher';
protected $fillable = [
'name'
];
}
教师链接:
class TeacherLink extends Authenticatable
{
protected $table = 'teacher_links';
protected $fillable = [
'teacher_id', 'school_id'
];
我可以使用 $school->teachers
在控制器中通过学校成功查询教师,所以我知道关系正常。
这是我的控制器代码,其中有条件地建立了用户搜索参数:
public function index(Request $request)
{
$schools = School::query();
// User Search Term
$search = $request->get('search');
$headTeacher = $request->get('head_teacher');
$questions
->when($search, function ($q) use ($search) {
$q->where('school_name', 'like', '%' . $search . '%')
->orWhere('head_teacher', 'like', '%' . $search . '%')
// This is the query i'm having an issue with
->whereHas('teachers', function($q) use ($search) {
$q->where('teacher_name', 'like', '%' . $search . '%');
});
})
}
两个首字母 where 子句 return 按学校名称或 head_teacher 搜索时的正确结果,因为这两个属性直接属于学校。但是,我想 return 其他学校通过关系包含教师姓名。
所以一所学校可以通过中间人 teacher_link table 属于许多教师,反之亦然,但我不知道如何使用 eloquent 查询生成器准确过滤这个.
最初我尝试使用 union 函数和连接,它起作用但破坏了后续的 where 子句,因为它似乎不允许在 union 查询后跟随 where 子句。
如果有人能告诉我我做错了什么以及如何解决有问题的查询,那就太好了:
// This is the query i'm having an issue with
->whereHas('teachers', function($q) use ($search) {
$q->where('teacher_name', 'like', '%' . $search . '%');
});
编辑
我尝试了以下方法,但似乎有效但速度很慢:
$schools
->when($search, function ($q) use ($search) {
$q->join("teacher_links", function ($join) {
$join->on("teacher_links.school_id", "=", "schools.id");
})
->join("teachers", function ($join) {
$join->on("teachers.id", "=", "teacher_links.teacher_id");
})
->select("schools.*")
->where("teachers.teacher_name", 'like', '%' . $search . '%')
->orWhere('school_name', 'like', '%' . $search . '%')
->orWhere('school_address', 'like', '%' . $search . '%')
->orWhere('school_focus', 'like', '%' . $search . '%');
});
尝试在该查询中使用 orWhereHas
。
->when($search, function ($q) use ($search) {
$q->where('school_name', 'like', '%' . $search . '%')
->orWhere('head_teacher', 'like', '%' . $search . '%')
->orWhereHas('teachers', function ($sub) use ($search) {
$sub->where('teacher_name', 'like', '%' . $search . '%');
});
});
尝试使用 eloquent 关系
School::where('school_name', 'like', '%' . $search . '%')
->orWhere('head_teacher', 'like', '%' . $search . '%')
->orWhereHas(['teachers'=>function($query) use ($search) {
return $query->where('teacher_name', 'like', '%' . $search . '%');
}]
)->get();
我正在使用 eloquent 查询构建器根据用户搜索查询提供的参数有条件地构建搜索查询。
这似乎适用于直接属于我正在搜索的模型的属性。但是,我在尝试 return 与模型相关但不直接属于模型的其他结果时遇到问题。
我到底想做什么:
我正在尝试允许用户通过中介 table.
按教师姓名搜索学校,其中 name/keyword 出现在学校的关系中这是我的模型和关系:
学校:
class School extends Authenticatable
{
protected $fillable = [
'school_name', 'head_teacher', 'address'
];
public function teachers()
{
return $this->belongsToMany(Teacher::class, 'teacher_links', 'school_id', 'teacher_id');
}
}
老师:
class Teacher extends Authenticatable
{
use Notifiable;
protected $table = 'teacher';
protected $fillable = [
'name'
];
}
教师链接:
class TeacherLink extends Authenticatable
{
protected $table = 'teacher_links';
protected $fillable = [
'teacher_id', 'school_id'
];
我可以使用 $school->teachers
在控制器中通过学校成功查询教师,所以我知道关系正常。
这是我的控制器代码,其中有条件地建立了用户搜索参数:
public function index(Request $request)
{
$schools = School::query();
// User Search Term
$search = $request->get('search');
$headTeacher = $request->get('head_teacher');
$questions
->when($search, function ($q) use ($search) {
$q->where('school_name', 'like', '%' . $search . '%')
->orWhere('head_teacher', 'like', '%' . $search . '%')
// This is the query i'm having an issue with
->whereHas('teachers', function($q) use ($search) {
$q->where('teacher_name', 'like', '%' . $search . '%');
});
})
}
两个首字母 where 子句 return 按学校名称或 head_teacher 搜索时的正确结果,因为这两个属性直接属于学校。但是,我想 return 其他学校通过关系包含教师姓名。
所以一所学校可以通过中间人 teacher_link table 属于许多教师,反之亦然,但我不知道如何使用 eloquent 查询生成器准确过滤这个.
最初我尝试使用 union 函数和连接,它起作用但破坏了后续的 where 子句,因为它似乎不允许在 union 查询后跟随 where 子句。
如果有人能告诉我我做错了什么以及如何解决有问题的查询,那就太好了:
// This is the query i'm having an issue with
->whereHas('teachers', function($q) use ($search) {
$q->where('teacher_name', 'like', '%' . $search . '%');
});
编辑
我尝试了以下方法,但似乎有效但速度很慢:
$schools
->when($search, function ($q) use ($search) {
$q->join("teacher_links", function ($join) {
$join->on("teacher_links.school_id", "=", "schools.id");
})
->join("teachers", function ($join) {
$join->on("teachers.id", "=", "teacher_links.teacher_id");
})
->select("schools.*")
->where("teachers.teacher_name", 'like', '%' . $search . '%')
->orWhere('school_name', 'like', '%' . $search . '%')
->orWhere('school_address', 'like', '%' . $search . '%')
->orWhere('school_focus', 'like', '%' . $search . '%');
});
尝试在该查询中使用 orWhereHas
。
->when($search, function ($q) use ($search) {
$q->where('school_name', 'like', '%' . $search . '%')
->orWhere('head_teacher', 'like', '%' . $search . '%')
->orWhereHas('teachers', function ($sub) use ($search) {
$sub->where('teacher_name', 'like', '%' . $search . '%');
});
});
尝试使用 eloquent 关系
School::where('school_name', 'like', '%' . $search . '%')
->orWhere('head_teacher', 'like', '%' . $search . '%')
->orWhereHas(['teachers'=>function($query) use ($search) {
return $query->where('teacher_name', 'like', '%' . $search . '%');
}]
)->get();