Выпуск коллекции Laravel

После долгих поисков и поиска в стеке, я решил, что мне нужна ваша помощь.

Я должен получить количество поставок для каждой поставки определенным поставщиком. Я знаю, это звучит странно, но позвольте мне объяснить:

У меня есть модель Поставщика, у которой много поставок, и у каждой поставки есть много запасов, у которых есть количество. Так что теперь я строю представление, в котором я хочу представить каждое предложение с их количеством по определенному поставщику.

Вот что я придумал в своем контроллере:

foreach ($suppliers as $supplier) {

        foreach($supplier->supplies as $supply){

            if(!$comp_supplies->contains('name', $supply->name)){

                $comp_supplies->push(['name'=>$supply->name, 'supplier'=>[['name'=> $supplier->name, 'quantity' => $supply->stocks->first()->quantity]]]);

            }elseif($comp_supplies->contains('name', $supply->name)){

                $array = (['name'=> $supplier->name, 'quantity' => $supply->stocks->first()->quantity]);
                $array2 = $comp_supplies->where('name', $supply->name)->first()['supplier'];

                array_push($array2, $array);

                //dd($array2);
                $comp_supplies->where('name', $supply->name)->first()['supplier'] = $array2;
                dd($comp_supplies->where('name', $supply->name)->first()['supplier']);
            }
        }

    }

Поэтому я перебираю своих поставщиков и снова перебираю поставки от каждого из них. Теперь я хочу заполнить коллекцию, которую я хочу в результате.

Если в этой коллекции нет источника с именем "$supply->name", я помещаю массив с именем источника и создаю массив "поставщики", в котором я также устанавливаю первую запись с информацией о текущем поставщике.

Теперь мы приближаемся к моей проблеме.

Если comp_supply уже содержит поставку с текущим именем поставки, если нужно вставить нового поставщика в уже существующий массив "поставщик", который мы создали в первом "если".

Поэтому я создал $ массив, который содержит новую информацию о поставщике, и $array2, который содержит массив поставщиков ($comp_supplies->where('name', $supply->name)->first()['supplier']) мы уже сделали.

Теперь, если я вставлю $ array в $ array2 и dd(array2), все будет работать так, как я хочу. Но если я сейчас установлю

$comp_supplies->where('name', $supply->name)->first()['supplier'] = $array2 

а потом

dd($comp_supplies->where('name', $supply->name)->first()['supplier']);

это не изменилось.

Я застрял в этой проблеме на 2 часа и очень расстроился.

Пожалуйста, если у кого-то есть идея, что я могу сделать, чтобы решить эту проблему, или если я знаю, где я могу искать дальше, дайте мне знать

Вот также миграции:

Поставщик:

public function up()
{
    Schema::create('suppliers', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name')->unique();
        $table->unsignedInteger('coordinates_id')->index()->nullable();
        $table->timestamps();
    });
}

Расходные материалы:

public function up()
{
    Schema::create('supplies', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->unsignedInteger('supplier_id');
        $table->foreign('supplier_id')
              ->references('id')
              ->on('suppliers')
              ->onDelete('cascade');
        $table->timestamps();
    });
}

Запасы:

    public function up()
{
    Schema::create('stocks', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('supplies_id');
        $table->foreign('supplies_id')
              ->references('id')
              ->on('supplies')
              ->onDelete('cascade');
        $table->integer('quantity');
        $table->timestamps();
    });
}

3 ответа

Ваша проблема связана с тем, как PHP работает с массивами. Массивы передаются по значению, а не по ссылке, поэтому при вызове $comp_supplies->where('name', $supply->name)->first()вы на самом деле получаете копию массива, и, следовательно, изменяя значение в индексе 'supplier' изменяет только значение копии, а не значение исходного массива.

Вы можете проверить это поведение с помощью этого примера кода:

class TestList
{
    protected $values;

    public function push($value)
    {
        $this->values[] = $value;
    }

    public function get($index)
    {
        return $this->values[$index];
    }
}

$list = new TestList();
$list->push(['test' => 1]);

var_dump($list->get(0)['test']); // int(1)

$list->get(0)['test'] = 2;
var_dump($list->get(0)['test']); // still int(1)... 

Вы можете решить эту проблему, используя объекты вместо массивов, потому что объекты передаются по ссылке (обратите внимание на (object) бросать):

$list = new TestList();
$list->push((object)['test' => 1]);

var_dump($list->get(0)->test); // int(1)

$list->get(0)->test = 2;
var_dump($list->get(0)->test); // int(2)!

Вместо

$comp_supplies->where('name', $supply->name)->first()['supplier'] = $array2;

Вы должны использовать:

$key = $comp_supplies->where('name', $supply->name)->get()->keys()->first();
$comp_supplies[$key]['supplier'] = $array2;

потому что вы вставляете в массивы коллекций, поэтому сначала вам нужно найти действительный ключ коллекции, чтобы позже вы могли обновить этот массив для этого ключа

Попробуй это

$comp_supplies->where('name', $supply->name)->first()->update($array2)

Вместо

$comp_supplies->where('name', $supply->name)->first()['supplier'] = $array2 
Другие вопросы по тегам