首页 > 解决方案 > 雄辩的范围 - 所有项目不是其他表中的 FK

问题描述

首先,了解我在创建查询范围时遇到的困难的一些背景知识。

这是我的架构的一部分:

Structure
 - id
 - head_office_id

Establishment
 - id
 - structure_id

这是我的模型中定义关系的方式

class Structure {    
    public function head_office(): BelongsTo
    {
        return $this->belongsTo(Establishment::class, 'head_office_id');
    }

    public function establishments(): HasMany
    {
        return $this->hasMany(Establishment::class);
    }

}

class Establishment {
    public function structure(): BelongsTo
    {
        return $this->belongsTo(Structure::class);
    }
}

我想对机构进行一个范围,可以排除作为其所属结构的总部的所有机构。

Establishment::notHeadOffice()->get()

例如:

Structures

id | head_office_id
1  | null
2  | 3

Establishments

id | structure_id
1  | 1
2  | 1
3  | 2
4  | 2
5  | 2

在这种情况下,范围应带回除 3 号以外的所有机构因为机构 3 与结构 2 相关联并且是该结构的总部)

我已经尝试了一些事情,但这超出了我对查询生成器的了解。

有什么线索吗?

PS:无法更改型号

标签: laraveleloquent

解决方案


您可以在范围方法中构建查询。

以下代码有效..

建立.php

namespace App;

use Illuminate\Database\Eloquent\Model;
use DB;

class Establishment extends Model
{

    public function scopeNotHeadOffice($query)
    {
        return $query->whereNotExists(function ($qry) {
            $qry->select(DB::raw(1))
                ->from('structures')
                ->whereRaw('structures.head_office_id = establishments.id');
        });
    }

    public function structure(): BelongsTo
    {
        return $this->belongsTo(Structure::class);
    }
}

控制器

Establishment::notHeadOffice()->get();

参考:

Laravel WhereExists - https://laravel.com/docs/6.x/queries#where-exists-clauses

Laravel WhereNotExists- https://stackoverflow.com/a/38575266

MySQL 存在 - http://www.mysqltutorial.org/mysql-exists/


推荐阅读