查询对象之间的间接关系

Querying indirect relationships between objects

提问人:miken32 提问时间:7/11/2018 最后编辑:miken32 更新时间:7/11/2018 访问量:43

问:

使用 Laravel 5.6,假设我有以下数据库表:

networks   users        vlans
--------   -----        -----
id         id           id
           network_id   network_id
           vlan_id

这些关系:

class Network extends Model {
    public function users() { return $this->hasMany("User"); }
    public function vlans() { return $this->hasMany("Vlan"); }
}

class User extends Model {
    public function network() { return $this->belongsTo("Network"); }
    public function vlan()    { return $this->belongsTo("Vlan"); }
}

class Vlan extends Model {
    public function network() { return $this->belongsTo("Network"); }
    public function user()    { return $this->hasOne("User"); }
}

我的问题是:给定一个 ID,有没有一种简单的方法来确定哪些对象没有分配给 ?NetworkVlanUser

这是非常早期的阶段(我对 Laravel 很陌生),所以如果我搞砸了关系,我会毫不犹豫地重新开始。我考虑过改变一些东西,使表有一个外键,但这似乎是倒退的。(这只会给我留下同样的问题:如何找到所有没有赋值的对象!vlansuser_idUserVlan

PHP Laravel 雄辩

评论

0赞 Chin Leung 7/11/2018
这是多对多的关系吗?例如,一个 VLAN 可以属于多个用户,一个用户可以拥有多个 VLAN?
0赞 Devon Bessemer 7/11/2018
您只能将一个 VLAN 分配给一个用户。
0赞 miken32 7/11/2018
@ChinLeung不,这是一对一的;VLAN 是用户独有的,用户只能有一个。
1赞 Don't Panic 7/11/2018
你见过这个吗?这可能会有所帮助:laravel.com/docs/5.6/...

答:

1赞 Chin Leung 7/11/2018 #1

您可以向 VLAN 模型添加作用域:

public function scopeNotAssigned($query, $id)
{
    return $query->whereNotIn(
        'id',
        User::where('network_id', $id)->select('vlan_id')->get()->pluck('vlan_id')->toArray()
    );
}

然后假设你有一个网络:

$network = \App\Network::first();

您可以像这样检索网络中未分配的 vlan:

$vlans = \App\Vlan::notAssigned($network->id)->get();

否则,您还可以在 VLAN 模型中添加与用户的关系:

public function user()
{
    return $this->hasOne('App\User');
}

然后,您可以使用以下功能:whereDoesntHave

$vlans = Vlan::whereDoesntHave('users', function ($query) use ($network) {
    return $query->where('network_id', $network->id);
})->get();