امیر حسین شریفی
5 سال پیش توسط امیر حسین شریفی مطرح شد
7 پاسخ

خطا در مایگریت کردن

سلام من طبق یه آموزشی یه تیبل برای رول ساختم بعد که بعد میاد این رو با تیبل کاربر ها و یه تیبل که کاربر ها رو به رول ها ارتباط میده رابطه مستقیم ایجاد میکنه.
الان من سه تا تیبل دارم
users
roles
role_user

تیبل یوز که همون معمولی ماله خوده لاراوله
اما این مایگریشن برای roles

Schema::create('roles', function (Blueprint $table) {
      $table->increments('id');
      $table->string('name');
      x$table->timestamps();
});

این هم مایگریشن مربوط به یوزر رول

Schema::create('role_user', function (Blueprint $table) {
      $table->integer('role_id')->unsigned();
      $table->integer('user_id')->unsigned();

      $table->foreign('role_id')->references('id')->on('roles')->onCascade('delete');
      $table->foreign('user_id')->references('id')->on('users')->onCascade('delete');
});

مشکل اینجاست که وقتی مایگریت میکنم خطای زیر رو میده

  SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `role_user` add constraint `role_user_user_id_foreign` foreign key (`user_id`) references `users` (`id`))
  • دست اخر یه سوال دیگ که آیا اصلا این روش برای ساخت رول درسته؟ زیادی تیبل درست نکردم؟

ثبت پرسش جدید
coarad supp
تخصص : برنامه نویس لاراول
@coaradsupp 5 سال پیش مطرح شد
2
Schema::create('roles', function (Blueprint $table) {
      $table->increments('id');
      $table->string('name');
      x$table->timestamps();
});
Schema::create('role_user', function (Blueprint $table) {
      $table->unsignedBigInteger('role_id');
      $table->unsignedBigInteger('user_id');

      $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade')->onUpdate('cascade');
      $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
});

به این شکل نباید مشکلی باشه، و همچنین دو مایگریت یوزر و رول باید بالاتر از مایگریت رول-یوزر باشن، تا خطایی رخ نده،

این موارد رو بررسی کنید


coarad supp
تخصص : برنامه نویس لاراول
@coaradsupp 5 سال پیش مطرح شد
1

به جای
Integer
از unsignedBigInteger
استفاده کنید

$table->unsignedBigInteger('user_id')->unsigned();

سبحان دادخواه
تخصص : دانشجوی برنامه نویسی :)
@SobhanDadkhah 5 سال پیش آپدیت شد
2

@amirsharifi سلام.
همونطوری که دوستمون @coaradsupp گفتن باید فیلد کلید خارجی از نوع bigInteger تعریف کنید . فقط خواستم دلیلشو براتون توضیح بدم که دلیل اصلیشو بدونید.
اگر اشتباه نکنم توی ورژن های 5.8 به بالای لاراول اومدن و مقدار دیفالت ستون id رو از integer معمولی به BigInteger تغییر دادن .یعنی این قسمت :

$table->increments('id');

برای شما یه فیلد id توی دیتابیس ایجاد میکنه که نوعش BigInt هست و موقع تعریف کلید خارجی قانونش این هست که تایپ کلید خارجیتون باید با تایپ رفرنسش برابر باشه و چون شما کلیدتون رو integer تعریف کردین تداخل ایجاد میشه .
کد صحیح :

Schema::create('role_user', function (Blueprint $table) {
      $table->bigInteger('role_id')->unsigned();
      $table->bigInteger('user_id')->unsigned();

      $table->foreign('role_id')->references('id')->on('roles')->onCascade('delete');
      $table->foreign('user_id')->references('id')->on('users')->onCascade('delete');
});

موفق باشید


امیر حسین شریفی
تخصص : Web Developer
@amirsharifi 5 سال پیش مطرح شد
0

@coaradsupp
@SobhanDadkhah

خیلی ممنون از هردوی شما دوست عزیز اما نه unsignedBigInteger و نه bigInteger خطای من رو بر طرف نکرد تا جایی که من متوجه شدم اگه id رو برای تیبل اول یعنی roles از

$table->increments('id');

به

$table->id();

تغییر بدم که دقیقا میشه مثله آی دی تیبل یوزر ها خطا بر طرف میشه.
اما چرا؟؟؟


سبحان دادخواه
تخصص : دانشجوی برنامه نویسی :)
@SobhanDadkhah 5 سال پیش مطرح شد
1

@amirsharifi یه مشکل جالبی که پیش اومد اینه :
توی کلید خارجیتون اصلا اون متد onCascade فک کنم وجود نداشته باشه و برعکس نوشتین من دقت نکردم قاعدتا باید onDelete رو cascade قرار بدین . 🧐
و اینکه الان که دقیقتر چک کردم :

  $table->increments('id'); // creates integer column

$table->id(); // creates bigInteger column called id

در واقع اگر هر دو جدول roles و users رو آیدی هاشون رو بصورتی که خودتون تعریف کرده بودین increments بذارید باید با همون کد اولیتون کار کنه یعنی به این صورت :

Schema::create('role_user', function (Blueprint $table) {
      $table->integer('role_id')->unsigned();
      $table->integer('user_id')->unsigned();

      $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
      $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});

فقط مطمین باشید که جای متد onDelete اشتباها onCascade ننویسید . و لطفا بعد از تست اگر امکانش هست نتیجشو اعلام کنید چون خیلی چالش قشنگی شد 😁


امیر حسین شریفی
تخصص : Web Developer
@amirsharifi 5 سال پیش آپدیت شد
0

@SobhanDadkhah
مرسی از وقتی ک میزارید .
این بخش onDelete رو درست گفتین مدرس اشتباه گفته بود.
خدمتتون بگم که متاسفانه بازم نشد اما بررسی من نشون میده که خطا مربوط به همین دو خط هست

$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

coarad supp
تخصص : برنامه نویس لاراول
@coaradsupp 5 سال پیش مطرح شد
2
Schema::create('roles', function (Blueprint $table) {
      $table->increments('id');
      $table->string('name');
      x$table->timestamps();
});
Schema::create('role_user', function (Blueprint $table) {
      $table->unsignedBigInteger('role_id');
      $table->unsignedBigInteger('user_id');

      $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade')->onUpdate('cascade');
      $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
});

به این شکل نباید مشکلی باشه، و همچنین دو مایگریت یوزر و رول باید بالاتر از مایگریت رول-یوزر باشن، تا خطایی رخ نده،

این موارد رو بررسی کنید


سبحان دادخواه
تخصص : دانشجوی برنامه نویسی :)
@SobhanDadkhah 5 سال پیش مطرح شد
1

@amirsharifi سلام مجدد . نظر دوستمون @coaradsupp هم کاملا درسته احتمالا مشکل از این قسمته . در واقع باید ترتیب مایگریشن ها جوری باشه که با دستورتون ابتدا جداول یوزر ها و رول ها ایجاد بشن و بعد جدول pivot


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام