查询对象之间的间接关系

时间:2018-07-10 19:14:02

标签: php laravel eloquent

使用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"); }
}

我的问题是:给定一个Network ID,是否有一种简单的方法来确定哪些Vlan对象未分配给User? >

这是非常早期的阶段(而且我对Laravel还是很陌生),因此,如果我搞砸了恋爱关系,那么我就不会重新开始。我已经考虑过进行更改,以使vlans表具有一个user_id外键,但这似乎倒退了。 (这只会给我一个相反的问题:如何查找所有没有User分配的Vlan对象!)

1 个答案:

答案 0 :(得分: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();