2014-07-06 137 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(); 

您可以添加檢查,以這種方法,所以它不會拋出異常,但它仍然不能用於急切的加載。