Eloquent Collection содержит () work, но diff () или intersect () считает, что все разные - PullRequest
0 голосов
/ 29 марта 2019

У меня есть массив строк, которые помогают мне инициировать и find() связанные модели.

$arr = [
   "App\Post"  => 1,
   "App\Video" => 1
];
// this array is [Model => ModelId]

На данный момент я инициирую класс модели из строки и использую find(), чтобы найти объект модели.

У меня также есть 2 отношения morphByMany() в моей модели User, которая возвращает мне коллекцию обоих.

// class User
public function entities() {
  // this returns merged collection successfully
  return ($this->videos)->merge($this->posts);
}

На этом этапе, если я попробую с contains(), , это будет работать :

foreach ($arr as $modelString => $modelId) {
     // this finds the related model:
     $model = $modelString::find($modelId)->first(); 

     $this->entities()->contains($model); // returns true
}

Однако, если я попытаюсь создать новую коллекцию на основе моих инициированных моделей, $collection->diff($collection2) или $collection->intersect($collection) не будет работать .

$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

(Просто чтобы очистить, и $this->entities(), и $arr имеют одинаковые модели. Единственное отличие состоит в том, что $this->entities() возвращает сводные значения вместе с моделью, тогда как значения, инициированные из $arr, не имеют; однако contains() работа.

Ответы [ 2 ]

0 голосов
/ 29 марта 2019

@ Чин Люн «Модель с отношениями, а другая модель без отношений считается другой». дал мне возможность думать по-другому.

$collection1 = $this->entities()->map(function($item) {
    return $item->unsetRelation('pivot');
});

А потом diff() и intersect() начали работать как положено!

0 голосов
/ 29 марта 2019

Я проверил это на последней версии Laravel и не могу воспроизвести ту часть, в которой вы упоминаете, ->contains возвращает true. Я получаю false, когда пытаюсь contains, как вы, что является ожидаемым поведением, потому что модель с отношениями и другая модель без отношений считаются разными.

Вы можете использовать функцию diffUsing, чтобы передать обратный вызов, чтобы проверить, совпадают ли класс и идентификатор элемента.

$c1->diffUsing($c2, function ($a, $b) {
    return get_class($a) != get_class($b) || $a->id != $b->id;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...