Вставка отношений "многие ко многим" в базе данных дает мне вызов функции-члена syn c () на null - PullRequest
1 голос
/ 06 августа 2020

У меня отношение many to many.

Quote Model

public function products(){
    return $this->belongsToMany(Product::class);
}

Product Model

public function quotes(){
    return $this->belongsToMany(Quote::class);
}

Я получаю сведения из формы ввода на свой Controller. Результат выглядит следующим образом:

array:39 [▼ 
"_token" => "NgcHxCjpGUe1ot8nJr4Z8VFuA3DG9VprKWqRu5yk"
"quote_id" => "52" 
20 => "0"
10 => "0"
11 => "0"
12 => "0"
13 => "0"
14 => "0"
15 => "0"
16 => "0"
17 => "0"

"quote_id" относится к цитате, созданной на шаге, предшествующем форме ввода, упомянутой выше. quote_id передается контроллеру из скрытого поля ввода в форме. В приведенном выше массиве $key относится к product_id, а $value относится к количеству продукта.

Я пытаюсь вставить данные в table product_quote.

Schema::create('product_quote', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('product_id');
        $table->unsignedBigInteger('quote_id');
        $table->integer('qty');
        $table->timestamps();
    });

Вот код, который у меня есть:

$data = $request->toArray();
$quote_id = $data['quote_id'];
    unset($data['quote_id']);
    $quote = Quote::query()->findOrFail($quote_id);
    foreach (array($data) as $key => $value){
        $quote->products->sync($data);
        $quote->save();
    }

Там после того, как мне все еще нужно добавить количество продукта, но я получаю сообщение об ошибке: вызов функции-члена syn c () на null.

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 06 августа 2020

Это неправильное понимание Коллекций и Отношений.

В Laravel, если у вас есть продукты отношения в вашем случае, чтобы получить доступ к отношению, которое вы вызовете.

$quote->products(); // returns belongsToMany relation query

Кому доступ к коллекции вы получаете доступ к ней как к свойству.

$quote->products; // returns a collection with the products

В вашем случае вы получаете доступ к ней как к коллекции. Если вы получаете нулевую ошибку, что-то еще может быть неправильным, но начните с изменения ее на следующее.

Во-вторых, чтобы установить сводные поля, используйте массив значений ключа при вызове syn c, используя ключ и ценность вашей структуры. Вероятно, вам также следует отключить токен. Вместо этого я фильтрую его, используя except. Лучшим подходом является использование проверенного в запросе формы.

Вам нужно будет настроить ваши данные, чтобы они соответствовали ожидаемой структуре значения ключа при вызове syn c, syn c также следует называть только одним поскольку он синхронизирует данные между каждым вызовом.

$data = $request->toArray();

$quote = Quote::findOrFail($data['quote_id']); // calling query() is unnecessary

$products = collect($request->except(['_token', 'quote_id']))->
    ->mapWithKeys(function($item, $key) {
        return [$key => ['qty' => $item]];
    })->all();

$quote->products()->sync($products);

В этом решении используется mapWithKeys, который позволяет вам управлять ключом и элементом в коллекции, а этот метод сбора используется не так часто. Возврат закрытия должен быть в формате return ['key' => 'item']; вместо return 'item';

.
0 голосов
/ 06 августа 2020

Вам нужно использовать отношения products, а не коллекцию.

$quote->products()->sync($data);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...