2014-07-06 136 views
2

我有三个表格:User,Client,Position。工作流程如下:雄辩的关系 - 关系的关系

  1. A client创建了自己的一套positions
  2. 一个client添加users它的管理,然后分配positions他们
  3. 一个user可以属于多个不同的clients

那么这些表之间的关系是:

  • ClientPosition:1对许多
  • PositionUser:许多一对多
  • ClientUser:很多多对一

因此当前LY,我的模型如下:

Class User extends Eloquent { 
    public function clients() 
    { 
     return $this->belongsToMany('Client'); 
    } 

    public function positions() 
    { 
     return $this->belongsToMany('Position'); 
    } 
} 

Class Client extends Eloquent { 
    public function users() 
    { 
     return $this->belongsToMany('User'); 
    } 

    public function positions() 
    { 
     return $this->hasMany('Position'); 
    } 
} 

// The Position model is not included, since it doesn't make sense to start from a position 

所以,说一个User属于两个Clients,以及他们对这些Clients不同Positions。一个例子是:

  • 我有两个客户:索尼和微软
  • 我有两个用户:约翰和迈克。
  • 微软拥有职位:开发人员和工程师。
  • 索尼有职位:市场营销和金融。
  • John在微软担任开发人员。
  • Mike在微软担任工程师,在索尼担任财务人员。

我想让迈克在微软的职位只有。现在,我知道如何做到这一点的唯一方法如下:

$c_id = $Microsoft_Id; 
$u_id = $Mike_Id; 
Client::find($c_id) 
     ->users() 
     ->whereId($u_id) 
     ->with(['positions' => function($query) use ($c_id) 
       { 
        $query->whereClientId($c_id); 
       } 
     ]) 
     ->get(); 

有没有我可以执行模型本身这个任务的方法吗?如果我只想说:

Client::find($c_id) 
     ->users() 
     ->whereId($u_id) 
     ->with('positions') 
     ->get(); 

而且检查在模型本身内执行。

+0

当您再次使用3个模型之间的m-m关系时,这是有意义的。看起来你不能查询'用户'''位置'没有'客户'的上下文,没有解释它? –

+0

是的,但由于我已经用'$ c_id'和'$ u_id'查询了它,我试图从关系中的'$ this'访问这些信息,然后限制返回的值。 – Kousha

+0

用户可以在一个客户端上拥有多个职位? –

回答

0

你可以使用这个,但是,它不会在预先加载工作,因为很明显$id将无法​​访问:

// Client model 
public function usersWithPositions() 
{ 
    $id = $this->getKey(); 

    return $this->belongsToMany('User')->with(['positions' => function ($q) use ($id) { 
     $q->whereClientId($id); 
    }]); 
} 

// will work 
$client = Client::find($c_id); 
$client->usersWithPositions; 
// or 
$Mike = $client->usersWithPositions()->where('users.id', $u_id)->first(); 


// won't work 
Client::with('usersWithPositions')->get(); 

您可以添加检查,以这种方法,所以它不会抛出异常,但它仍然不能用于急切的加载。