I have 2 models User and Publisher, linked with with a manytomany relationship. When I try to loop through each publisher a user has and pluck the ID to an array, the loop runs the correct number of times (5 in this instance), but the query returns every publisher ID, not just those in the relationship.
User model has
public function publishers()
{
return $this->belongsToMany('App\Publisher')->withTimestamps();
}
and Publisher model has
public function users()
{
return $this->belongsToMany('App\User')->withTimestamps();
}
My foreach loop like this
foreach ($user->publishers as $uPublisher) {
$userPublisherIds[] = $uPublisher->pluck('id')->toarray();
}
I know I can use array_merge to build the array, I am just using [] now to see how many times the loop is iterating.
I can't work out why $user->publishers gives me the expected filtered collection, but $uPublishers returns every publisher ID. It's very strange.
Can anybody suggest why this might be?
The pluck()
method exists on both Collections and the Database Builder. When you call $uPublisher->pluck()
, it's making a new database call, identical to if you ran Publisher::pluck()
.
Inside your foreach
, $uPublisher
is a single model result, not a collection. Because of Eloquent's Active Record ORM nature, a single model instance can still act like a query builder/executor on its respective table.
$uPublisher->pluck()
gets forwarded to Model::__call()
, which bubbles up to Builder::pluck()
, which runs a new query against that model/table.
As you've tried, $user->publishers
returns a collection, which you could run pluck
against to get all the IDs. Within your loop, you wouldn't call pluck
, you'd just access the ID property directly:
$userPublisherIds[] = $uPublisher->id;