Laravel WhereHas with polymorphic relations
laravel, laravel-4, mysql, php, polymorphic-associations
Solution
Although I don't know what the question is, I bet you actually get the correct answer and your expectation is incorrect.
Your second example with a single `whereHas` obviously does not return any rows, because the condition is never satisfiable.
For the first however, I guess your understanding is flawed. The generated query reflects what you specify with the two `whereHas` clauses. It will find all enterprises which have at least one label which is hidden, and at least one label which is not hidden. Since it's a many-many relationship, this is in fact satisfiable.
Note that this is different from the second example, where you search for all enterprises which have at least one label which is both hidden and not hidden.
I do not know the enterprises table, nor the many-many join table, but I guess the two results actually satisfy the condition as I stated above. Your database engine probably does not lie. If you think otherwise and have a feeling the generated query is actually wrong, please tell us where you think it is wrong.
Problem
it seems like the whereHas method doesn't work really well. ``` $res = Entreprise::whereHas('labels',function ($q) { $q->where('hidden','!=',1); }) ->whereHas('labels',function ($q) { $q->whereHidden(1); }) ->get(); dd(count($res)); //shows int 2 ``` Here is the labels relations: ``` public function labels() { return $this->morphToMany('Label', 'labelable'); } ``` and here is the database: ``` 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 ``` When I do instead: ``` $res = Entreprise::whereHas('labels',function ($q) { $q->where('hidden','!=',1); $q->whereHidden(1); })->get() dd(count($res)); //int 0 ``` I get the expected value. In my database, an entreprise object doesn't have more than 1 labels, so the label is either hidden or not, so one of the conditions should be false. Edit Here is the labelable table ``` +----+----------+--------------+----------------+-----------+ | 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 | +----+----------+--------------+----------------+-----------+ ``` As you can see, the problem is probably that they are two entities with labelable_id of 1, and two entities of labelable_id of 2. But this is a morphToMany, so Eloquent should know that the labels on users should not be taken into account ? When I have a look at the generated 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` = ?) >= ? ``` it seems like the `labelables.labelable_type` isn't taken into account, so that may be the source of the problem.