簡體   English   中英

Laravel 按屬性獲取雄辯的查詢構建器關系

[英]Laravel get eloquent query builder relations by property

我正在使用 eloquent 查詢構建器根據用戶搜索查詢提供的參數有條件地構建搜索查詢。

這似乎適用於直接屬於我正在搜索的模型的屬性。 但是,在嘗試返回與模型相關但不直接屬於模型的其他結果時,我遇到了問題。

我正在嘗試做的正是:

我試圖允許用戶按教師姓名搜索學校,其中姓名/關鍵字通過中間表出現在學校的關系中。

這是我的模型和關系:

學校:

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 teachers 通過控制器中的學校成功查詢$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 . '%');
                });

        })

}

當按學校名稱或 head_teacher 搜索時,兩個初始 where 子句返回正確的結果,因為這兩個屬性直接屬於一個學校。 但是,我想通過這種關系返回包含教師姓名的其他學校。

因此,一所學校可以通過中間的 Teacher_link 表屬於許多教師,反之亦然,但我不知道如何使用 eloquent 查詢構建器准確地過濾這一點。

最初,我嘗試使用 union 函數和 joins 工作,但破壞了后續的 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 . '%');
        });
    });

嘗試使用雄辯的關系

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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM