I have an array of strings that helps me to initiate and find()
the related models.
$arr = [
"App\Post" => 1,
"App\Video" => 1
];
// this array is [Model => ModelId]
At this point, I am initiating model class from string and using find()
to find the model object.
I also have 2 relationships of morphByMany()
in my User model that returns me a collection of both.
// class User
public function entities() {
// this returns merged collection successfully
return ($this->videos)->merge($this->posts);
}
At this point, if I try with contains()
, it works:
foreach ($arr as $modelString => $modelId) {
// this finds the related model:
$model = $modelString::find($modelId)->first();
$this->entities()->contains($model); // returns true
}
However, if I try to create a new collection based on my initiated models, $collection->diff($collection2)
or $collection->intersect($collection)
doesn't work.
$collection1 = $this->entities();
$collection2 = collect();
foreach ($arr as $modelString => $modelId) {
$model = $modelString::find($modelId)->first();
$collection2->push($model);
}
$collection1->diff($collection2); // returns all items
$collection1->intersect($collection2); // returns []
// intersect() and diff() should be other way around
(Just to clear, both $this->entities()
and $arr
have same models. The only difference is $this->entities()
return pivot values along with the model whereas the ones initiated from $arr
doesn't; however contains()
work.
I've tested this on the latest version of Laravel and I can't replicate the part where you mention ->contains
returns true
. I get false
when I try the contains
like you do, which is the expected behaviour because a model with relationship and another model without the relationship is considered different.
You could use the function diffUsing
to pass a callback to check if the class and the id of the item is the same or not.
$c1->diffUsing($c2, function ($a, $b) {
return get_class($a) != get_class($b) || $a->id != $b->id;
});
@Chin Leung's "a model with relationship and another model without the relationship is considered different." gave me the way to think in a different approach.
$collection1 = $this->entities()->map(function($item) {
return $item->unsetRelation('pivot');
});
And then, diff()
and intersect()
started working as expected!