2016-11-04 71 views
1

我有兩個模型,UserSeminar。在英語中,基本思想是一羣用戶參加任何數量的研討會。此外,每個研討會上只有一名用戶可以自願發言。Laravel - Flatten data via`with`

我的實現由users表,seminars表和seminar_user數據透視表組成。

seminar_user表有這樣的結構:

seminar_id | user_id | speaking 
-------------|-----------|--------- 
    int  | int | bool 

的關係定義如下:

/** On the Seminar model */ 
public function members() 
{ 
    return $this->belongsToMany(User::class); 
} 

/** On the User model */ 
public function seminars() 
{ 
    return $this->belongsToMany(Seminar::class); 
} 

我竭力要弄清楚如何設置當中,將會以「關係」幫助我獲得研討會的演講者。我目前已經定義的方法是這樣的:

public function speaker() 
{ 
    return $this->members()->where('speaking', true); 
} 

我想其原因,這是因爲最終,我想我的API調用看起來像這樣:

public function index() 
{ 
    return Seminar::active() 
     ->with(['speaker' => function ($query) { 
      $query->select('name'); 
     }]) 
     ->get() 
     ->toJson(); 
} 

的問題是由於members關係實際上是一個belongsToMany,即使我知道只有一個User其中speaking爲真,一個User的數組將始終返回。

一個解決辦法是後格式化發送它,首先設置一個臨時$seminars變量,然後通過foreach去和設置每個$seminar['speaker'] = $seminar['speaker'][0]前的響應,但真的很臭,我覺得應該有辦法通過雄辯本身實現這一點。

如何將通過with調用添加的數據變平? (或重寫我的關係方法)

回答

1

試着改變你的speaker功能,這

public function speaker() 
{ 
    return $this->members()->where('speaking', true)->first(); 
} 

這將永遠給你一個項目,而不是你目前收到的集合。

+1

這會不會讓你玩與查詢,並且不會讓您使用'with'作爲模型中的關係熱切加載它。 –

+0

@JosephSilber可能會......但這會解決OP的問題。 – linuxartisan

+0

謝謝@JosephSilber ...這正是我沒有采用這種方法的原因。 – tam5

0

您可以在Seminar模型定義了一個新的關係:

public function speaker() 
{ 
    return $this->belongsToMany(User::class)->wherePivot('speaking', true); 
} 

和您的查詢就會爲:

Seminar::active() 
    ->with(['speaker' => function ($query) { 
     $query->select('name'); 
    }]) 
    ->get() 
    ->toJson(); 

Docs向下滾動到Filtering Relationships Via Intermediate Table Columns

+0

實際上,這段代碼和我目前所擁有的唯一區別就是你已經把'where'改成'wherePivot'。在這種情況下,它會返回完全相同的結果,因此您的解決方案會得到與我已有的結果相同的結果。:( – tam5

+0

區別也是'$ this-> belongsToMany()'。你試過嗎? –

+0

實際上,我調用'members'函數返回相同的'belongsToMany',這就是爲什麼我說它是不管怎樣,是的,我已經嘗試過了,問題是'belongsToMany'假定多個值可能被取回,所以它返回一個對象數組,即使只有一個值存在。 – tam5