Eloquent Collection包含()工作,但diff()或intersect()认为所有都是不同的

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!