Как исправить нарушение ограничения целостности: 1062 Повторяющаяся запись '1-1' для ключа 'ОСНОВНОЙ: Сводная таблица Laravel - PullRequest
0 голосов
/ 16 января 2019

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

  • Ребенок может иметь столько пользователей (спонсоров), сколько их слотов им позволяют.
  • Пользователи могут спонсировать одного ребенка, нескольких детей ИЛИ одного и того же ребенка несколько раз при необходимости.

Я создал сводную таблицу для спонсоров, детей и пользователей. При первой транзакции связь в таблице правильная, но если пользователь возвращается и снова спонсирует дочерний процесс для 2-го или 3-го слота, я получаю следующую ошибку:

SQLSTATE [23000]: нарушение ограничения целостности: 1062 Повторяющаяся запись «1-1» для ключа «ПЕРВИЧНЫЙ» (23000)

kid_user сводная таблица:

public function up()
{
    Schema::create('kid_user', function (Blueprint $table) {
        $table->integer('kid_id')->unsigned()->index();
        $table->foreign('kid_id')->references('id')->on('kids')->onDelete('cascade');
        $table->integer('user_id')->unsigned()->index();
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        $table->primary(['kid_id', 'user_id']);
        $table->timestamps();
    });
}

Малыш Модель:

  public function users() {
        return $this->belongsToMany(User::class)->withTimestamps();
  }

Модель пользователя:

  public function kids(){
       return $this->belongsToMany(Kid::class)->withTimestamps();
  }

Присоединение в моем контроллере с этой строкой:

        $cin = $request->cin;
        $kidid = $request->kidid;

        $kids = DB::table('kids')->where('cin', $cin)->increment('sponsors_received');
        $user = Auth::user();
        $user->kids()->attach($kidid);
        //$user->kids()->sync($kidid);
;

Что я сейчас получаю:

+--------------------+
|   kid_user table   | 
+--------------------+
| *kid_id | *user_id | * = Primary Key
+---------+----------+
|    1    |     1    | -> Sponsored 1st Slot
+---------+----------+

Что я хочу получить:

+--------------------+
|   kid_user table   | THE BELOW RESULTS ARE WHAT I'M LOOKING FOR.
+--------------------+
| *kid_id | *user_id | * = Primary Key
+---------+----------+
|    1    |     1    | -> Sponsored 1st Slot (CURRENTLY GETTING)
+---------+----------+
|    1    |     1    | -> Sponsored 2nd Slot (ERRORS HERE!!!)
+---------+----------+
|    2    |     1    | -> Sponsored 3rd Slot (THIS WILL WORK)
+---------+----------+

Я пытался использовать sync вместо attach в моем контроллере, но sync просто перезаписывает первое отношение, добавляя новое, чтобы показать, что пользователь спонсирует 1-й и 2-й слот ребенка из 3 слота.

Также пытался использовать отношение hasMany в моих моделях, но это не помогло. В качестве последней попытки я также добавил созданные / обновленные столбцы в надежде, что это сделает его уникальным, но не повезло.

Ответы [ 2 ]

0 голосов
/ 16 января 2019

Да, я согласен с ответом @ Набила. Существует проблема с дизайном базы данных. Приложение выдает ошибку из-за уникального ограничения в таблицах БД. Либо придерживайтесь предложенного им подхода, либо вы также можете добавить поле подсчета. Я полагаю, вы хотите знать, сколько спонсоров получил ребенок? Сделайте все эти поля уникальными (kid_id, user_id, slots)

0 голосов
/ 16 января 2019

Проблема в дизайне базы данных. В вашей таблице набор ('kid_id', 'user_id') должен быть уникальным. Но второе (1,1) в вашем примере неверно, потому что уже есть набор (1,1).

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

| pivot_id*| kid_id | user_id |  * = Primary Key
+---------+---------+----------+
|    1    |    1    |     1    | -> Sponsored 1st Slot (CURRENTLY GETTING)
+---------+---------+----------+
|    2    |    1    |     1    | -> Sponsored 2nd Slot (SAME DATA WITH DIFFERENT KEY)
+---------+---------+----------+
|    3    |    2    |     1    | -> Sponsored 3rd Slot (THIS WILL WORK)
...