2013-12-23 3 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 

Я получаю ожидаемое значение ,

В моей базе данных объект entreprise не содержит более 1 метки, поэтому ярлык скрыт или нет, поэтому одно из условий должно быть ложным.

Редактировать

Вот labelable таблица

+----+----------+--------------+----------------+-----------+ 
| 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 | 
+----+----------+--------------+----------------+-----------+ 

Как вы можете видеть, проблема, вероятно, что они являются два лица с labelable_id 1, и два объекта из labelable_id 2. Но это morphToMany, поэтому Eloquent должен знать, что метки на пользователях не следует принимать во внимание?

Когда я взглянуть на сгенерированный 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

Эй, мой вопрос в том, что, учитывая, что у компаний есть только один label в моей базе данных, я не понимаю, почему первый синтаксис показывает результаты, а второй - нет. @marcanuy: это была просто опечатка, я отредактировал код. – edi9999

ответ

3

Хотя я не знаю, в чем вопрос, держу пари, вы действительно получаете правильный ответ, и ваше ожидание неверно.

Ваш второй пример с одним whereHas, очевидно, не возвращает никаких строк, потому что условие никогда не выполняется.

Для первого, однако, я думаю, ваше понимание ошибочно. Сгенерированный запрос отражает то, что вы указываете, с двумя предложениями whereHas. Он найдет все предприятия, у которых есть хотя бы одна метка, которая скрыта, и по крайней мере одна метка, которая не скрыта. Поскольку это много-много отношений, это на самом деле выполнимо.

Обратите внимание, что это отличается от второго примера, где вы ищете все предприятия, имеющие хотя бы одну метку, которая скрыта и не скрыта.

Я не знаю таблицу предприятий, а также таблицу со многими многими соединениями, но я думаю, что два результата действительно удовлетворяют условию, как я уже говорил выше. Возможно, ваш механизм базы данных не лжет. Если вы думаете иначе, и у вас есть ощущение, что сгенерированный запрос на самом деле ошибочен, сообщите нам, где вы думаете, что это неправильно.

+0

Эй, я понимаю, почему две части кода не ведут себя одинаково для общих данных (например, у entreprise может быть одна скрытая и одна видимая метка). Но в моем случае (см. Database_dump ярлыков), у entreprise только одна метка в то время, поэтому я не понимаю, почему это не работает. Похоже, что это связано с тем, что антреприз и пользователь имеют один и тот же labelable_id, но это все еще странно, потому что это полиморфное отношение. – edi9999

+0

Я вижу. Тогда это действительно является ошибкой в ​​Laravel 'hasWhere' для полиморфных отношений. Вы можете указать ошибку на http://github.com/laravel/framework – Joost

+2

Просто добавив ссылку на отчет об ошибке для всех, кто попадает сюда через поиск, https://github.com/laravel/framework/issues/ 3068 –

Смежные вопросы