2013-12-23 99 views
3

它似乎像whereHas方法不能很好地工作。Laravel WhereHas與多態關係

$res = Entreprise::whereHas('labels',function ($q) 
    { 
     $q->where('hidden','!=',1); 
    }) 
    ->whereHas('labels',function ($q) 
    { 
     $q->whereHidden(1); 
    }) 
    ->get(); 
dd(count($res)); //shows int 2 

這裏是標籤的關係:

public function labels() 
{ 
    return $this->morphToMany('Label', 'labelable'); 
} 

這裏是數據庫:

id | nom    | deleted_at | created_at   | updated_at   | junior_id | label_type_id | abbreviation | id_siaje | hidden 
6 | Environnord  | 0000-00-00 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |   1 |    4 | EnvNord  |  0 |  1 
7 | Salon créer  | 0000-00-00 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |   1 |    4 | Créer  |  0 |  1 
8 | Salon WebAnalytics | 0000-00-00 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |   1 |    4 | Web   |  0 |  0 

當我這樣做,而不是:

$res = Entreprise::whereHas('labels',function ($q) 
    { 
     $q->where('hidden','!=',1); 
     $q->whereHidden(1); 
    })->get() 
dd(count($res)); //int 0 

我得到的預期值。

在我的數據庫中,企業對象沒有超過1個標籤,因此標籤不是隱藏的,所以其中一個條件應該是false。

編輯

這裏是可加標籤表

+----+----------+--------------+----------------+-----------+ 
| id | label_id | labelable_id | labelable_type | junior_id | 
+----+----------+--------------+----------------+-----------+ 
| 1 |  1 |   925 | Etude   |   1 | 
| 2 |  2 |   926 | Etude   |   1 | 
| 3 |  3 |   927 | Etude   |   1 | 
| 4 |  2 |   927 | Etude   |   1 | 
| 5 |  1 |   928 | Etude   |   1 | 
| 6 |  2 |   928 | Etude   |   1 | 
| 7 |  3 |   929 | Etude   |   1 | 
| 8 |  2 |   931 | Etude   |   1 | 
| 9 |  1 |   933 | Etude   |   1 | 
| 10 |  2 |   934 | Etude   |   1 | 
| 11 |  4 |   1 | User   |   1 | 
| 12 |  5 |   2 | User   |   1 | 
| 13 |  7 |   1 | Entreprise  |   1 | 
| 14 |  6 |   2 | Entreprise  |   1 | 
| 15 |  7 |   3 | Entreprise  |   1 | 
| 16 |  8 |   4 | Entreprise  |   1 | 
| 17 |  6 |   5 | Entreprise  |   1 | 
| 18 |  7 |   6 | Entreprise  |   1 | 
| 19 |  6 |   7 | Entreprise  |   1 | 
+----+----------+--------------+----------------+-----------+ 

正如你所看到的,這個問題可能是,他們是兩個實體的1 labelable_id,和2 labelable_id的兩個實體。但是這是一個morphToMany,所以雄辯應該知道用戶的標籤不應該被考慮在內?

當我看看生成的SQL:

select * from `entreprises` 
    where `entreprises`.`deleted_at` is null 
    and `entreprises`.`junior_id` = ? 
    and (select count(*) from `labels` 
      inner join `labelables` on `labels`.`id` = `labelables`.`label_id` 
      where `labels`.`deleted_at` is null 
      and `labels`.`junior_id` = ? 
      and `labelables`.`labelable_id` = `entreprises`.`id` 
      and `hidden` != ? 
      and `hidden` = ? 
      and `labels`.`deleted_at` is null 
      and `labels`.`junior_id` = ?) >= ? 

它好像labelables.labelable_type沒有考慮到,這樣可能是問題的根源。

+0

你的問題是什麼? –

+0

是「return $ this-> morphToMany('Label','labelable')/ * - > select(」問題中的錯字或這是真實的代碼? – marcanuy

+0

嘿,我的問題是,由於企業只有一個標籤在我的數據庫中,我不明白爲什麼第一個語法顯示結果,第二個沒有。@marcanuy:這只是一個錯字,我已經編輯了代碼。 – edi9999

回答

3

雖然我不知道問題是什麼,但我敢打賭,你實際上得到了正確的答案,並且你的期望是不正確的。

你的第二個例子只有一個whereHas顯然不會返回任何行,因爲這個條件永遠不能滿足。

首先,我想你的理解是有缺陷的。生成的查詢反映了您使用兩個whereHas子句指定的內容。它會查找所有至少有一個隱藏標籤的企業,以及至少一個未隱藏的標籤。由於它是多種關係,這實際上是可以滿足的。

請注意,這與第二個示例不同,您可以在其中搜索所有至少有一個標籤既隱藏又不隱藏的企業。

我不知道企業表,也沒有多少連接表,但我猜這兩個結果實際上是滿足上述條件。你的數據庫引擎可能不會說謊。如果您以其他方式思考並且感覺生成的查詢實際上是錯誤的,請告訴我們您認爲哪裏錯了。

+0

嘿,我明白爲什麼這兩部分代碼不會以相同的方式表現一般數據(例如企業可能有一個隱藏的標籤和一個可見的標籤)。但就我而言(請參閱las lables的database_dump),企業當時只有一個標籤,所以我不明白爲什麼這不起作用。看起來這是因爲一個企業和一個用戶有相同的labelable_id,但它仍然很奇怪,因爲它是多態關係。 – edi9999

+0

我明白了。那麼這確實是Laravel的'hasWhere'多態關係中的一個錯誤。您可以在http://github.com/laravel/framework – Joost

+2

上提交錯誤。只需通過搜索添加對任何其他人的bug報告的引用,即https://github.com/laravel/framework/issues/ 3068 –