25

In my application I have updated a relationship from one-to-many to many-to-many and I'm trying to figure out a way to persist associated functionality.

Let's say I have two related tables, e.g. dogs and owners. If I have an array of owners and I'm trying to get a list of dogs id's for those owners, how should I do it eloquently?

Similar question was asked here: https://laracasts.com/discuss/channels/laravel/getting-many-to-many-related-data-for-an-array-of-elements

So, How would I get the Dog models where Owner is in an array ?

Same thing as $associatedDogs = Dog::whereIn('owner_id',$ListOfOwners)->get(); is for a One-To-Many relationship, but for Many-to-Many.

Davide Casiraghi
  • 15,591
  • 9
  • 34
  • 56
Angelin Calu
  • 1,905
  • 8
  • 24
  • 44

3 Answers3

68

Use the whereHas() method:

$dogs = Dog::whereHas('owners', function($q) use($ownerIds) {
    $q->whereIn('id', $ownerIds);
})->get();
Brett
  • 1,951
  • 2
  • 28
  • 35
Alexey Mezenin
  • 158,981
  • 26
  • 290
  • 279
  • Should I choose the `whereHas` over `with` ? What is the difference between them in this case? Does it even make any difference? – Angelin Calu Mar 09 '17 at 10:01
  • Nevermind, I found the explaination here: http://stackoverflow.com/a/30232227/2012740 – Angelin Calu Mar 09 '17 at 10:28
  • @AngelinCalu yes, `with()` will not work for you, since it loads relation data. – Alexey Mezenin Mar 09 '17 at 13:15
  • @ I haven't actually tried the `with` method because of what I have read. So if I understood correctly, that it will probably work also, however it will eager load the `owner`s associated with the `dog`s – Angelin Calu Mar 09 '17 at 13:20
  • 1
    @AngelinCalu no `with()` will not work. It will load all dogs and filtered owners. `whereHas()` will load only dogs with owners which are in the list. Just try both and you'll see the difference. – Alexey Mezenin Mar 09 '17 at 13:28
  • 1
    Says Ambiguous Id in where clause is there any solution to that ? – Sagar Gautam Jul 05 '20 at 08:56
3

I tried the two suggested solutions but I was getting an error that said that id was not unique. I solved like this:

$dogs = Dog::whereHas('owners', function($q) use($ownerIds) {
    $q->whereIn('owner_id', $ownerIds);
})->get();
Davide Casiraghi
  • 15,591
  • 9
  • 34
  • 56
2

Try

$associateDogs = Dog::with(['owners' => function($query) use ($listOfOwners) {
    $query->whereIn('id', $listOfOwners);
}])->get();
EddyTheDove
  • 12,979
  • 2
  • 37
  • 45