Повторяющаяся запись ключа при обновлении объекта - PullRequest
1 голос
/ 04 ноября 2019

У меня есть Product объект, который имеет несколько Shop объектов, потому что магазин может предлагать один и тот же продукт по разным ценам / условиям.

У меня есть представление редактирования продуктов, в котором перечислены магазины, гдепродукт доступен.

Когда я делаю корректировки в магазинах продукта, например. цена;Я получаю сообщение об ошибке, что магазин уже существует в базе данных. Я знаю, что продукт существует, но мне нужно обновить данные.

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-1' for key 'PRIMARY'

    public function update(Request $request, $slug)
    {
        $product = Product::with('shops', 'type')->where('slug', $slug)->first();
       [... snip ...]

        $i = 0;
        foreach($product->shops as $shop) {
            $shop = request('shop');
            $product->shops()->attach($product->id, [
              'shop_id' => $shop[$i]['id'],
              'price' => $shop[$i]['price'],
              'url' => $shop[$i]['url']
            ]);
            $i++;
        }

        $product->save();

      return redirect('/'.$slug)->with('success', 'Product has been updated');
    }

$product->update(); дает тот же результат.

РЕДАКТИРОВАТЬ:

Product.php

class Product extends Model
{

    protected $appends = ['lowest_price'];

    public function shops(){
        return $this->belongsToMany('App\Shop')->withPivot('price','url');
    }

    public function type(){
        return $this->belongsTo('App\Type');
    }

    public function getLowestPriceAttribute()
    {
        $lowest_price = NULL;
        foreach($this->shops as $shop) {
            if(is_null($lowest_price)) { 
                $lowest_price = (double)$shop->pivot->price;
            }

            if($lowest_price > (double)$shop->pivot->price) {
                $lowest_price = (double)$shop->pivot->price;
            }
        }
        return $lowest_price;
    }

}

Shop.php

class Shop extends Model
{
    //
}

Миграция магазина

public function up()
    {
        Schema::create('shops', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('url');
            $table->string('logo');
            $table->timestamps();
        });

        [... snip ...]
    }

EDIT2:

Подробнее об ошибке:

 Illuminate \ Database \ QueryException (23000)
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-1' for key 'PRIMARY' (SQL: insert into `product_shop` (`price`, `product_id`, `shop_id`, `url`) values (500.00, 1, 1, http://test.com))
'CREATE TABLE `products` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `make` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `model` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `description` text COLLATE utf8_unicode_ci NOT NULL,
  `image` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `video` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `manufacturer_specs` text COLLATE utf8_unicode_ci NOT NULL,
  `top_speed` decimal(8,1) NOT NULL,
  `range` decimal(8,1) NOT NULL,
  `weight` decimal(8,1) NOT NULL,
  `type_id` int(10) unsigned NOT NULL,
  `slug` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `lowest_price` decimal(8,1) NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `products_slug_unique` (`slug`),
  KEY `products_type_id_index` (`type_id`),
  CONSTRAINT `products_type_id_foreign` FOREIGN KEY (`type_id`) REFERENCES `types` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci'
'CREATE TABLE `product_shop` (
  `product_id` int(10) unsigned NOT NULL,
  `shop_id` int(10) unsigned NOT NULL,
  `price` decimal(8,2) NOT NULL,
  `url` text COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`product_id`,`shop_id`),
  KEY `product_shop_product_id_index` (`product_id`),
  KEY `product_shop_shop_id_index` (`shop_id`),
  CONSTRAINT `product_shop_product_id_foreign` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE CASCADE,
  CONSTRAINT `product_shop_shop_id_foreign` FOREIGN KEY (`shop_id`) REFERENCES `shops` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci'
'CREATE TABLE `shops` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `url` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `logo` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci'

Edit3: если я нажму кнопку обновления, яполучить ошибку, даже если я ничего не изменил enter image description here

1 Ответ

2 голосов
/ 04 ноября 2019

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

Вместо использования attach вы можете использовать sync:

$product->shops()->sync(
    [
        $shop[$i]['id'] => [
            'price' => $shop[$i]['price'],
            'url' => $shop[$i]['url']
        ]
    ], false);

Важной частью является второй параметр, который отключил detaching другие связанные элементы. Вы также можете использовать syncWithoutDetaching.

Подробнее см .:

Документы

API

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...