代码之家  ›  专栏  ›  技术社区  ›  miken32 Amit D

查询对象间的间接关系

  •  2
  • miken32 Amit D  · 技术社区  · 6 年前

    使用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 ?

    这是非常早期的阶段(我对拉拉维尔还很陌生),所以如果我把关系搞砸了,我对重新开始毫无疑问。我考虑过改变一些事情, vlans 表有一个 user_id 但这似乎是倒退。(这会给我留下一个相反的问题:如何找到所有 用户 对象没有 虚拟局域网 任务!)

    1 回复  |  直到 6 年前
        1
  •  1
  •   Chin Leung    6 年前

    您可以向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();